簡體   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