Свойство C#, действительно ли возможно двигаться, определение добираются, не определяя набор (никакая переменная поддержки)?

можно рассмотреть что-то как этот:

  1. определяют стиль для textblock или любое другое управление, которое Вы хотите использовать для отображения перечисления:

        <Style x:Key="enumStyle" TargetType="{x:Type TextBlock}">
            <Setter Property="Text" Value="&lt;NULL&gt;"/>
            <Style.Triggers>
                <Trigger Property="Tag">
                    <Trigger.Value>
                        <proj:YourEnum>Value1<proj:YourEnum>
                    </Trigger.Value>
                    <Setter Property="Text" Value="{DynamicResource yourFriendlyValue1}"/>
                </Trigger>
                <!-- add more triggers here to reflect your enum -->
            </Style.Triggers>
        </Style>
    
  2. определяют Ваш стиль для ComboBoxItem

        <Style TargetType="{x:Type ComboBoxItem}">
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock Tag="{Binding}" Style="{StaticResource enumStyle}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
  3. , добавляет поле комбинированного списка и загружает его Вашими перечислимыми значениями:

            <ComboBox SelectedValue="{Binding Path=your property goes here}" SelectedValuePath="Content">
                <ComboBox.Items>
                    <ComboBoxItem>
                        <proj:YourEnum>Value1</proj:YourEnum>
                    </ComboBoxItem>
                </ComboBox.Items>
            </ComboBox>
    

, если Ваше перечисление является большим, можно, конечно, сделать то же в коде, экономя большой ввод. мне нравится этот подход, так как он делает локализацию легкой - Вы определяете все шаблоны однажды, и затем, Вы только обновляете свои файлы строкового ресурса.

7
задан Craig Stuntz 3 December 2009 в 14:08
поделиться

8 ответов

You could create a new value type that pretends to be a decimal, but returns the rounded value. Something like this:

struct RoundedDecimal
{
    public decimal Value { get; private set; }

    public RoundedDecimal(decimal value) : this()
    {
        this.Value = value;
    }

    public static implicit operator decimal(RoundedDecimal d)
    {
        return Math.Round(d.Value);
    }
}

Each property in your class should be of type RoundedDecimal instead of decimal.

5
ответ дан 6 December 2019 в 12:52
поделиться

No. If you need any custom logic in either getter or setter, you cannot use auto-properties.

6
ответ дан 6 December 2019 в 12:52
поделиться

Easiest way to refactor the code? Here's what I would do:

  1. Open Notepad++ (get it if you don't have it)
  2. Copy/paste all properties of the class into a blank text area.
  3. Place the cursor at the start of the first line: public decimal MathValue1 { get; set; }
  4. Start recording a macro (click the record button on the toolbar)
  5. hold down ctrl+right arrow (called "word right") 3 times to put the cursor at the beginning of the property name.
  6. do shift+ctrl+right arrow 1 time and do a Copy to put the name of the property in the clipboard
  7. word right 3 more times to put the cursor after the "get"
  8. delete the semi-colon after the get and start typing " { return Math.Round(_"
  9. do a Paste 10 type "); }"
  10. word right 2 more times to put the cursor after the "set"
  11. delete the semi-colon after the set and start typing " { _"
  12. do a Paste
  13. type " = value; }
  14. press the End key to get the cursor to the end of the line
  15. press the right arrow key to get the cursor to the beginning of the next line.
  16. press the stop button to end your macro (square button on the toolbar)
  17. Click the "Run a macro multiple times" button (a double-arrow icon on the toolbar) and say "Run until the end of file"
  18. Copy/paste the resulting text back into your class to replace the original property definitions.

Now you'll need to define a set of corresponding private variables that begin with an underscore but otherwise have the same names as the properties. Start with a fresh copy of the properties from your class and perform a similar set of steps as described above.

My assumption is that each line starts with 2 tabs and there are no empty lines between properties.

Rather than having each property call Math.Round, you may want to consider defining your own utility function that they all call so that if you need to change it again, you can just change it in one place.

4
ответ дан 6 December 2019 в 12:52
поделиться

You could create a derivative of this class that overrides the gets and returns the rounded values. You would then need to modify the base property to be virtual. But that would allow you to define the get without defining the set and using auto properties.

public class Base
{
    public virtual decimal MathValue { get; set; }
}

public class Derived : Base
{
    public override decimal MathValue
    {
        get { return Math.Round(base.MathValue); }
    }
}
1
ответ дан 6 December 2019 в 12:52
поделиться

But what happens if the client doesn't want a rounded value? ie, some new client code sets a decimal and expects that "exact" value back?

If some clients really need the output of the property call to be rounded, then the client should handle this and leave your class alone.

0
ответ дан 6 December 2019 в 12:52
поделиться

Visual Studio used to have a built-in "prop" code snippet that would generate something like the following code:

    private decimal _MathValue;

    public decimal MathValue
    {
        get { return _MathValue; }
        set { _MathValue = value; }
    }

That would get you most of the way to a complete solution, but since VS 2008 it now generates the automatic property version:

    public decimal MathValue { get; set; }

I haven't tried this yet, but here is a suggestion for creating your own code snippet to get the VS 2005 version of the "prop" code snippet back:

0
ответ дан 6 December 2019 в 12:52
поделиться

You could do this with PostSharp or some other .NET-based AOP framework. Here is the MethodExecutionEventArgs.ReturnValue property that says it can be used to "modify the return value..."

This will do it:

[Serializable]
public class RoundingAttribute : OnMethodBoundaryAspect
{
    public override void OnExit(MethodExecutionEventArgs eventArgs)
    {
        base.OnExit(eventArgs);
        eventArgs.ReturnValue = Math.Round((double)eventArgs.ReturnValue, 2);
    }
}

class MyClass
{
    public double NotRounded { get; set; }

    public double Rounded { [Rounding] get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        var c = new MyClass
                {
                    Rounded = 1.99999, 
                    NotRounded = 1.99999
                };

        Console.WriteLine("Rounded = {0}", c.Rounded); // Writes 2
        Console.WriteLine("Not Rounded = {0}", c.NotRounded);  // Writes 1.99999
    }
}
0
ответ дан 6 December 2019 в 12:52
поделиться

One option is to use aspect-oriented programming to intercept the property invocations on return and round the return value before passing control back to the caller.

0
ответ дан 6 December 2019 в 12:52
поделиться
Другие вопросы по тегам:

Похожие вопросы: