WPF 中带有 INotifyPropertyChanged 的绑定列表
BindingList with INotifyPropertyChanged in WPF
要让 UI 得到通知,属性 "差异 的正确方法是什么? " 在以下代码示例中发生了变化?
属性 是只读的。 属性 的值必须始终根据其他属性计算。
MainWindow.xaml:
<Window x:Name="winCalcs" x:Class="BindingList.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:BindingList"
Title="Calculations" Height="350" Width="525">
<Window.Resources>
<m:OperationList x:Key="OperationData"/>
<CollectionViewSource x:Key="Operations"
Source="{StaticResource ResourceKey=OperationData}"/>
</Window.Resources>
<Grid>
<TabControl x:Name="tabsMain">
<TabItem x:Name="tab01" Header="Tab 1">
<DataGrid x:Name="dg01"
ItemsSource="{Binding
Source={StaticResource ResourceKey=Operations},
UpdateSourceTrigger=PropertyChanged}" />
</TabItem>
<TabItem x:Name="tab02" Header="Tab 2">
<DataGrid x:Name="dg02"
ItemsSource="{Binding
Source={StaticResource ResourceKey=Operations},
UpdateSourceTrigger=PropertyChanged}" />
</TabItem>
</TabControl>
</Grid>
</Window>
Operation.cs:
namespace BindingList
{
class Operation : INotifyPropertyChanged
{
private float _minuend;
private float _subtrahend;
public float Minuend
{
get
{
return this._minuend;
}
set
{
if (this._minuend == value) return;
this._minuend = value;
this.NotifyPropertyChanged("Minuend");
}
}
public float Subtrahend
{
get
{
return this._subtrahend;
}
set
{
if (this._subtrahend == value) return;
this._subtrahend = value;
this.NotifyPropertyChanged("Subtrahend");
}
}
public float Difference
{
get
{
return Minuend - Subtrahend;
}
private set {}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string p)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
}
OperationList.cs:
namespace BindingList
{
class OperationList : BindingList<Operation>
{
public OperationList()
{
Add(new Operation());
}
}
}
当 Minuend 或 Subtrahend 改变时,Difference 改变。这意味着您需要在 Minuend 或 Subtrahend 的集合中通知 Difference 的变化。
差异不需要属性setter。
附带说明一下,没有必要在任何地方都使用 this
public float Minuend
{
get
{
return _minuend;
}
set
{
if (_minuend == value) return;
_minuend = value;
NotifyPropertyChanged("Minuend");
NotifyPropertyChanged("Difference");
}
}
public float Subtrahend
{
get
{
return _subtrahend;
}
set
{
if (_subtrahend == value) return;
_subtrahend = value;
NotifyPropertyChanged("Subtrahend");
NotifyPropertyChanged("Difference");
}
}
public float Difference
{
get
{
return Minuend - Subtrahend;
}
}
在这些情况下,我通常会显式设置 属性 并引发 PropertyChanged
事件。
namespace BindingList
{
class Operation : INotifyPropertyChanged
{
private float _minuend;
private float _subtrahend;
private float _difference;
public float Minuend
{
get
{
return this._minuend;
}
set
{
if (this._minuend == value)
return;
this._minuend = value;
this.NotifyPropertyChanged("Minuend");
this.UpdateDifference();
}
}
public float Subtrahend
{
get
{
return this._subtrahend;
}
set
{
if (this._subtrahend == value)
return;
this._subtrahend = value;
this.NotifyPropertyChanged("Subtrahend");
this.UpdateDifference();
}
}
private void UpdateDifference()
{
this.Difference = this.Minuend - this.Subtrahend;
}
public float Difference
{
get
{
return this._difference
}
private set
{
if (this._difference == value)
return;
this._difference = value;
this.NotifyPropertyChanged("Difference");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string p)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
}
要让 UI 得到通知,属性 "差异 的正确方法是什么? " 在以下代码示例中发生了变化?
属性 是只读的。 属性 的值必须始终根据其他属性计算。
MainWindow.xaml:
<Window x:Name="winCalcs" x:Class="BindingList.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:BindingList"
Title="Calculations" Height="350" Width="525">
<Window.Resources>
<m:OperationList x:Key="OperationData"/>
<CollectionViewSource x:Key="Operations"
Source="{StaticResource ResourceKey=OperationData}"/>
</Window.Resources>
<Grid>
<TabControl x:Name="tabsMain">
<TabItem x:Name="tab01" Header="Tab 1">
<DataGrid x:Name="dg01"
ItemsSource="{Binding
Source={StaticResource ResourceKey=Operations},
UpdateSourceTrigger=PropertyChanged}" />
</TabItem>
<TabItem x:Name="tab02" Header="Tab 2">
<DataGrid x:Name="dg02"
ItemsSource="{Binding
Source={StaticResource ResourceKey=Operations},
UpdateSourceTrigger=PropertyChanged}" />
</TabItem>
</TabControl>
</Grid>
</Window>
Operation.cs:
namespace BindingList
{
class Operation : INotifyPropertyChanged
{
private float _minuend;
private float _subtrahend;
public float Minuend
{
get
{
return this._minuend;
}
set
{
if (this._minuend == value) return;
this._minuend = value;
this.NotifyPropertyChanged("Minuend");
}
}
public float Subtrahend
{
get
{
return this._subtrahend;
}
set
{
if (this._subtrahend == value) return;
this._subtrahend = value;
this.NotifyPropertyChanged("Subtrahend");
}
}
public float Difference
{
get
{
return Minuend - Subtrahend;
}
private set {}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string p)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
}
OperationList.cs:
namespace BindingList
{
class OperationList : BindingList<Operation>
{
public OperationList()
{
Add(new Operation());
}
}
}
Difference 改变。这意味着您需要在 Minuend 或 Subtrahend 的集合中通知 Difference 的变化。
差异不需要属性setter。
附带说明一下,没有必要在任何地方都使用 this
public float Minuend
{
get
{
return _minuend;
}
set
{
if (_minuend == value) return;
_minuend = value;
NotifyPropertyChanged("Minuend");
NotifyPropertyChanged("Difference");
}
}
public float Subtrahend
{
get
{
return _subtrahend;
}
set
{
if (_subtrahend == value) return;
_subtrahend = value;
NotifyPropertyChanged("Subtrahend");
NotifyPropertyChanged("Difference");
}
}
public float Difference
{
get
{
return Minuend - Subtrahend;
}
}
在这些情况下,我通常会显式设置 属性 并引发 PropertyChanged
事件。
namespace BindingList
{
class Operation : INotifyPropertyChanged
{
private float _minuend;
private float _subtrahend;
private float _difference;
public float Minuend
{
get
{
return this._minuend;
}
set
{
if (this._minuend == value)
return;
this._minuend = value;
this.NotifyPropertyChanged("Minuend");
this.UpdateDifference();
}
}
public float Subtrahend
{
get
{
return this._subtrahend;
}
set
{
if (this._subtrahend == value)
return;
this._subtrahend = value;
this.NotifyPropertyChanged("Subtrahend");
this.UpdateDifference();
}
}
private void UpdateDifference()
{
this.Difference = this.Minuend - this.Subtrahend;
}
public float Difference
{
get
{
return this._difference
}
private set
{
if (this._difference == value)
return;
this._difference = value;
this.NotifyPropertyChanged("Difference");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string p)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(p));
}
}
}