我想,一旦我改变了txtA的值,txtB和txtC就会自动改变,因为我已经为ValueA实现了INotifyPropertyChanged。
但他们没有在UI上更新。 txtB总是100,而txtC总是-50。
我不知道是什么原因。
我的Xaml ..
<Window x:Class="WpfApplicationReviewDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<StackPanel>
<TextBox Name="txtA" Text="{Binding ValueA}" />
<TextBox Name="txtB" Text="{Binding ValueB}" />
<TextBox Name="txtC" Text="{Binding ValueC}" />
</StackPanel>
</Window>
我的代码背后......
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = new Model();
}
}
public class Model : INotifyPropertyChanged
{
private decimal valueA;
public decimal ValueA { get {
return valueA;
}
set
{
valueA = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueA"));
}
}
private decimal valueB;
public decimal ValueB
{
get
{
valueB = ValueA + 100;
return valueB;
}
set
{
valueB = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueB"));
}
}
private decimal valueC;
public decimal ValueC
{
get
{
valueC = ValueA - 50;
return valueC;
}
set
{
valueC = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueC"));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
在我将代码添加到ValueA属性的set方法之后,它可以正常工作。
public decimal ValueA { get {
return valueA;
}
set
{
valueA = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueA"));
PropertyChanged(this, new PropertyChangedEventArgs("ValueB"));
PropertyChanged(this, new PropertyChangedEventArgs("ValueC"));
}
}
但我认为应该为txtB和txtC自动刷新/更新。请指教。
答案 0 :(得分:3)
我会这样做
public class Model : INotifyPropertyChanged
{
private decimal valueA;
public decimal ValueA
{
get { return valueA; }
set
{
if( valueA != value )
{
valueA = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueA"));
PropertyChanged(this, new PropertyChangedEventArgs("ValueB"));
PropertyChanged(this, new PropertyChangedEventArgs("ValueC"));
}
}
}
public decimal ValueB
{
get { return ValueA + 100; }
}
public decimal ValueC
{
get { return ValueA - 50; }
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
或
public class Model2 : INotifyPropertyChanged
{
private decimal valueA;
private decimal valueB;
private decimal valueC;
public decimal ValueA
{
get { return valueA; }
set
{
if( valueA != value )
{
valueA = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueA"));
ValueB = value + 100;
ValueC = value - 50;
}
}
}
public decimal ValueB
{
get { return valueB; }
private set
{
valueB = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueB"));
}
}
public decimal ValueC
{
get { return valueC; }
private set
{
valueC = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueC"));
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
答案 1 :(得分:1)
开箱即用,它不知道物业B&amp; C依赖于A.你需要告诉它你已经完成了。
答案 2 :(得分:1)
PropertyChanged
允许任何数据绑定到属性已更改的对象。更改文本框的值时,请遵循代码的逻辑。为ValueA调用set方法,并将valueA设置为value。
set
{
valueA = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueA"));
}
然而,当调用PropertyChanged时,它所做的只是让TextBox知道值已经改变(它已经知道了,因为它调用了set方法)。另一个第二组方法的作用是它通知其他TextBox,它们的属性也发生了变化,所以它们需要反映这些变化。
set
{
valueA = value;
PropertyChanged(this, new PropertyChangedEventArgs("ValueA"));
PropertyChanged(this, new PropertyChangedEventArgs("ValueB"));
PropertyChanged(this, new PropertyChangedEventArgs("ValueC"));
}
这使得所有三个TextBox都可以更新显示以显示新值。
答案 3 :(得分:0)
您正在谈论的场景通常被称为“计算”或“计算”属性。但是,通常建议将它们设为只读。只读计算简化了代码,意味着您不需要有支持字段来存储值。
正如您已经解决的那样,INotifyPropertyChanged不会“自动”检测这些依赖关系。您需要根据依赖项显式触发事件。
这实际上是使用ILWeaving的完美案例。原因是在编译时ILWeaving可以检测到这些依赖关系并正确地触发多个事件。
例如,如果您使用NotifyPropertyWeaver http://code.google.com/p/notifypropertyweaver/,则可以像这样编写代码。
public class Model : INotifyPropertyChanged
{
public decimal ValueA { get; set; }
public decimal ValueB
{
get { return ValueA + 100;}
}
public decimal ValueC
{
get { return ValueA - 50; }
}
public event PropertyChangedEventHandler PropertyChanged;
}
并编译了这个
public class Model : INotifyPropertyChanged
{
public virtual void OnPropertyChanged(string propertyName)
{
var propertyChanged = PropertyChanged;
if (propertyChanged != null)
{
propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
decimal valueA;
public decimal ValueA
{
get { return valueA; }
set
{
if (!decimal.Equals(valueA, value))
{
valueA = value;
OnPropertyChanged("ValueB");
OnPropertyChanged("ValueC");
OnPropertyChanged("ValueA");
}
}
}
public decimal ValueB
{
get { return ValueA + 100;}
}
public decimal ValueC
{
get { return ValueA - 50; }
}
public event PropertyChangedEventHandler PropertyChanged;
}
请注意,OnPropertyChanged方法已经与三个调用一起注入了“A”的setter中。
请注意,“B”和“C”文本框也应该是只读的
<TextBox Name="txtA" Text="{Binding ValueA}" />
<TextBox Name="txtB" Text="{Binding ValueB}" IsReadOnly="True" />
<TextBox Name="txtC" Text="{Binding ValueC}" IsReadOnly="True" />