简体   繁体   English

在C#WPF中实现INotifyPropertyChanged

[英]Implementing INotifyPropertyChanged in C# WPF

I am pretty new to C# and WPF framework,my question might sound silly. 我对C#和WPF框架很陌生,我的问题可能听起来很愚蠢。 I am using the two-way binding feature. 我正在使用双向绑定功能。 So I implement INotifyPropertyChanged interface. 所以我实现了INotifyPropertyChanged接口。 I have a property named DisplayFormat, so whenever the format changes from Binary to Hex, my text should convert accordingly. 我有一个名为DisplayFormat的属性,因此每当格式从Binary更改为Hex时,我的文本都应相应地进行转换。 My question is where should I include the code/logic for the conversion between Binary and decimal? 我的问题是我应该在哪里包含二进制和十进制之间转换的代码/逻辑?

[DefaultValue(displayFormat.Binary)]
public displayFormat DisplayFormat
{
    get { return this.format; }
    set { this.format = value; OnPropertyChanged("DisplayFormat"); }
}

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged(string name)
{
    PropertyChangedEventHandler handler = PropertyChanged;
    if (handler != null)
    {
        handler(this, new PropertyChangedEventArgs(name));
    }
}

Another converter approach would be to use a MultiValueConverter. 另一种转换方法是使用MultiValueConverter。 This does not require the dependency property or additional NotifyPropertyChanged. 这不需要依赖属性或其他NotifyPropertyChanged。 The important thing to know about MultiValueConverter is that you get the "values" in the order that you put them in XAML. 关于MultiValueConverter的重要一点是,您按照将它们放入XAML的顺序获取“值”。

The converter becomes: 转换器变为:

public class NumberToSpecialStringConverter : IMultiValueConverter
{
    public Convert(...)
    {
       //This is going to the UI, from the Model
       return (value[1] as DisplayFormat).Convert(value[0]); //Or whatever you have
    }

    public ConvertBack(...)
    {
       //This is going to the Model, from the UI
       return (value[1] as DisplayFormat).ConvertBack(value[0]); //Or whatever you have
    }
}

The XAML: XAML:

<Window.Resources>
   <local:NumberToSpecialStringConverter x:Key="FormatConverter"/>
</Window.Resources>
...
<TextBlock>
   <MultiBinding Converter="{StaticResource FormatConverter}">
      <Binding Path="MyValue"/>
      <Binding Path="DisplayFormat"/>
   </MultiBinding>
</TextBlock>

No other changes are required. 无需其他更改。

What can be done is have two properties, both binded to your DisplayFormat property. 可以做的是有两个属性,都绑定到您的DisplayFormat属性。 When a Hex value should be presented, you may set the visibility of the Binary content control (maybe a TextBlock ) to false and only present your Hex values TextBlock , and the other way around for Binary values. 当应该显示十六进制值时,您可以将二进制内容控件(可能是TextBlock )的可见性设置为false,并仅显示十六进制值TextBlockTextBlock则为二进制值。 This can be achieved using an EventTrigger on the NotifyPropertyChanged of DisplayFormat . 这可以使用DisplayFormatNotifyPropertyChanged上的EventTrigger来实现。

Another approach would be to use a IValueConverter on your DisplayFormat property and have the logic for checking Hex or Binary and returning the proper format. 另一种方法是在DisplayFormat属性上使用IValueConverter ,并具有检查Hex或Binary并返回正确格式的逻辑。 That way you may present tge appropriate format for each value. 这样,您可以为每个值提供适当的格式。

A possible IValueConverter implementation: 一个可能的IValueConverter实现:

public class BinaryOrHexConverter : IValueConverter    
{        
    public object Convert(object value, Type targetType, object parameter,
                  System.Globalization.CultureInfo culture)        
    {
        int result;
        return int.TryParse(inputString, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out result) ? result.ToString() : value.ToString() // Assuming default is binary
    }

public object ConvertBack(object value, Type targetType, object parameter,
                System.Globalization.CultureInfo culture)
{
    return DependencyProperty.UnsetValue;
}            

} }

Whenever you need to convert something to something else, you use a converter . 每当您需要将某些内容转换为其他内容时,您就会使用转换器 A converter is just a class that implements IValueConverter . 转换器只是一个实现IValueConverter的类。

public class NumberToSpecialStringConverter : IValueConverter
{
   ...
}

Converters take two inputs, the value (whatever is actually displayed or bound to) and a parameter. 转换器接受两个输入,即值(实际显示或绑定的值)和参数。 The parameter can be whatever you want, but cannot be bound. 参数可以是您想要的任何值,但不能绑定。 Since you want a bound parameter, we need to inherit from DependencyObject as well and declare a DependencyProperty to bind to: 由于您需要绑定参数,我们还需要继承DependencyObject并声明DependencyProperty以绑定到:

public class NumberToSpecialStringConverter : DependencyObject, IValueConverter
{
    public displayFormat CurrentFormat
    { //Dependency property stuff }

    //Other DP stuff, use the 'propdp' snippet to get it all, or look on MSDN

    public Convert(...)
    {
       //This is going to the UI, from the Model
       return displayFormat.Convert(value); //Or whatever you have
    }

    public ConvertBack(...)
    {
       //This is going to the Model, from the UI
       return displayFormat.ConvertBack(value); //Or whatever you have
    }
}

Now that you have that, you just need to declare and use it: 既然你已经拥有它,你只需要声明并使用它:

<Window.Resources>
   <local:NumberToSpecialStringConverter x:Key="FormatConverter" CurrentFormat="{Binding DisplayFormat}"/>
</Window.Resources>
...
<TextBlock Text="{Binding Path=MyValue, Converter={StaticResource FormatConverter}"/>

There is one more catch. 还有一个问题。 Changing "DisplayFormat" will cause NotifyPropertyChanged to fire, which will update the value inside the converter. 更改“DisplayFormat”将导致NotifyPropertyChanged触发,这将更新转换器内的值。 However, the UI isn't running the convert function because it doesn't think anything has changed. 但是,UI没有运行转换功能,因为它认为没有任何改变。 Thus, you need to "pretend" that the value changed by invoking its NotifyPropertyChanged as well: 因此,你需要“假装”,该值通过调用 NotifyPropertyChanged以及改变:

[DefaultValue(displayFormat.Binary)]
public displayFormat DisplayFormat
{
    get { return this.format; }
    set
    { 
        this.format = value; 
        OnPropertyChanged("DisplayFormat"); 
        OnPropertyChanged("MyValue");
    }
}

Now the UI will perform a fresh "get" and conversion and display what you wanted! 现在,用户界面将执行全新的“获取”和转换,并显示您想要的内容!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM