作为练习,我决定在WPF中创建一个自行车齿轮计算器。我创建了两个私有字段,其中包含触发OnPropertyChanged()
的setter,但我有一个数据绑定属性ratio
,其行为为" readonly",因为它是动态计算的。当我运行程序时,文本框显示,初始值正确显示,"工作"显示属性更改处理程序中的单词,但ratio
TextBlock不会更新。
我怀疑这是由于该属性的方式" getted",我想知道是否绝对有必要为每个人添加一个私有字段,我想知道是否应该有任何DependencyProperty。 ..但实际上我已经达到了我的知识限制,无法让这个简单的程序工作。
这是我的模特:
class SingleGearsetModel : INotifyPropertyChanged
{
public SingleGearsetModel()
{
crank = 44;
cog = 16;
}
private int _crank;
private int _cog;
public int crank {
get{return _crank;}
set{
_crank = value;
OnPropertyChanged("crank");
}
}
public int cog {
get{return _cog;}
set{
_cog = value;
OnPropertyChanged("cog");
}
}
public double ratio
{
get {
return (double)crank / (double)cog;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string arg)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(arg));
Console.Writeline("working");
}
}
} // end class
这是我的XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="CalculadorFixaWPF.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<DockPanel x:Name="LayoutRoot">
<TextBox Text="{Binding crank, Mode=TwoWay}"/>
<TextBox Text="{Binding cog, Mode=TwoWay}"/>
<TextBlock Text="{Binding ratio, StringFormat={}{0:0.00}}"/>
</DockPanel>
</Window>
这是我的代码隐藏(MainWindow.xaml.cs):
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
this.DataContext = new SingleGearsetModel();
}
}
感谢阅读!
答案 0 :(得分:7)
由于Ratio是计算字段,因此您希望每次值更改时添加通知。如果更改了crank
或cog
,就会发生这种情况。
因此,在您通知他们被更改之后,还要通知ratio
已更改:
public int crank
{
get{return _crank;}
set{
_crank = value;
OnPropertyChanged("crank");
// *** Notify that ratio has also been changed ***
OnPropertyChanged("ratio");
}
}
同样适用于cog
。
修改强> 根据您的意见,以下是如何从类中注册PropertyChanged事件并提升PropertyChanged的比率:
// Constructor
public SingleGearsetModel()
{
....
PropertyChanged += SingleGearsetModel_PropertyChanged;
}
// PropertyChanged event handler
void SingleGearsetModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "cog" || e.PropertyName == "crank")
{
OnPropertyChanged("ratio");
}
}
使用这种方法,您不需要在属性的setter中添加OnPropertyChanged("ratio")
- 无论何时引发它们,您都会获得事件(在SingleGearsetModel_PropertyChanged
中)并提升{{1 }}
答案 1 :(得分:2)
最简单的方法就是将OnPropertyChanged("ratio")
添加到crank
和cog
的设置者中。您可以在监听来自OnPropertyChanged
和crank
的{{1}}事件时执行更复杂的操作,并在其中任何一个更改时自动触发cog
,但这至少会让你去。