![](/img/trans.png)
[英]C# - Implementing INotifyPropertyChanged to ObservableCollection
[英]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,並僅顯示十六進制值TextBlock
, TextBlock
則為二進制值。 這可以使用DisplayFormat
的NotifyPropertyChanged
上的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.