繁体   English   中英

在C#WPF中实现INotifyPropertyChanged

[英]Implementing INotifyPropertyChanged in C# WPF

我对C#和WPF框架很陌生,我的问题可能听起来很愚蠢。 我正在使用双向绑定功能。 所以我实现了INotifyPropertyChanged接口。 我有一个名为DisplayFormat的属性,因此每当格式从Binary更改为Hex时,我的文本都应相应地进行转换。 我的问题是我应该在哪里包含二进制和十进制之间转换的代码/逻辑?

[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));
    }
}

另一种转换方法是使用MultiValueConverter。 这不需要依赖属性或其他NotifyPropertyChanged。 关于MultiValueConverter的重要一点是,您按照将它们放入XAML的顺序获取“值”。

转换器变为:

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
    }
}

XAML:

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

无需其他更改。

可以做的是有两个属性,都绑定到您的DisplayFormat属性。 当应该显示十六进制值时,您可以将二进制内容控件(可能是TextBlock )的可见性设置为false,并仅显示十六进制值TextBlockTextBlock则为二进制值。 这可以使用DisplayFormatNotifyPropertyChanged上的EventTrigger来实现。

另一种方法是在DisplayFormat属性上使用IValueConverter ,并具有检查Hex或Binary并返回正确格式的逻辑。 这样,您可以为每个值提供适当的格式。

一个可能的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;
}            

}

每当您需要将某些内容转换为其他内容时,您就会使用转换器 转换器只是一个实现IValueConverter的类。

public class NumberToSpecialStringConverter : IValueConverter
{
   ...
}

转换器接受两个输入,即值(实际显示或绑定的值)和参数。 参数可以是您想要的任何值,但不能绑定。 由于您需要绑定参数,我们还需要继承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
    }
}

既然你已经拥有它,你只需要声明并使用它:

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

还有一个问题。 更改“DisplayFormat”将导致NotifyPropertyChanged触发,这将更新转换器内的值。 但是,UI没有运行转换功能,因为它认为没有任何改变。 因此,你需要“假装”,该值通过调用 NotifyPropertyChanged以及改变:

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

现在,用户界面将执行全新的“获取”和转换,并显示您想要的内容!

暂无
暂无

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

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