通知WPF中计算的数据绑定属性的更改

hel*_*ker 9 data-binding wpf notifications

作为练习,我决定在WPF中创建一个自行车齿轮计算器.我创建了两个私有字段,其中包含触发器OnPropertyChanged(),但我有一个数据绑定属性ratio,其行为为"只读",因为它是动态计算的.当我运行程序时,文本框显示,初始值正确显示,属性更改处理程序中的"工作"单词显示,但ratioTextBlock不更新.

我怀疑这是由于属性被"哄骗"的方式,我想知道是否绝对有必要为每个人添加一个私有字段,我想知道是否应该有任何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
Run Code Online (Sandbox Code Playgroud)

这是我的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>
Run Code Online (Sandbox Code Playgroud)

这是我的代码隐藏(MainWindow.xaml.cs):

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();
        this.DataContext = new SingleGearsetModel();
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢阅读!

Bla*_*hma 11

由于Ratio是计算字段,因此您希望每次值更改时都添加通知.如果crankcog更改,将发生这种情况.

因此,在您通知他们被更改后,也通知ratio已更改:

public int crank 
{ 
    get{return _crank;}
    set{
        _crank = value;
        OnPropertyChanged("crank");

        // *** Notify that ratio has also been changed ***
        OnPropertyChanged("ratio");
    }
}
Run Code Online (Sandbox Code Playgroud)

同样如此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");
        }
}
Run Code Online (Sandbox Code Playgroud)

使用这种方法,您不需要OnPropertyChanged("ratio")在属性的setter中添加内容- 无论何时引发它们,您都会获得事件(in SingleGearsetModel_PropertyChanged)并引发OnPropertyChanged("ratio")