为了账号安全,请及时绑定邮箱和手机立即绑定

INotifyPropertyChanged 和他的空事件

INotifyPropertyChanged 和他的空事件

C#
米脂 2022-12-24 12:26:24
我想用名称“CurrentMoney”更新 WPF 表单上的标签;我编写了从“INotifyPropertyChanged”实现的类 Money。UPD:我通过创建 ViewModelBase 类更改为 MVVM 模式。仍然有“PropertyChaged”为空。如何解决它以及为什么会发生?Money.cs    public class Money : ViewModelBase {    private double currentMoney;    public double CurrentMoney {        get => currentMoney;        set {            currentMoney = value;            OnPropertyChanged("CurrentMoney");        }    }    public Money() => currentMoney = 10000;    public int addMoney(double count) {        CurrentMoney += count;        return 1;    }           public int subMoney(double count) {        CurrentMoney -= count;        if (currentMoney < 0)            return 100;        return 1;    }}主窗口.cspublic partial class MainWindow : Window {    public Money currentMoney;    public MainWindow ( ) {        InitializeComponent();        currentMoney = new Money();        CurrentMoney.DataContext = currentMoney;    }    private void Initialize() {        CurrentMoney.Content = "Current money: " + currentMoney.CurrentMoney;        CurrentPollution.Content = CurrentPollution.Content.ToString() + Pollution.CurrentPollution;        Facktories.Content = Facktories.Content.ToString() + FactoriesList.Quantity;        FactoriesPollution.Content = FactoriesPollution.Content.ToString() + FactoriesList.FullPolution;    }    private void MenuItem_Click(object sender, RoutedEventArgs e) {        var buy = new BuySMTH();        this.Visibility = Visibility.Collapsed;        buy.Show();    }    private void Window_ContentRendered(object sender, EventArgs e) {                   Initialize();    }    private void Tmp_Click(object sender, RoutedEventArgs e) {        currentMoney.addMoney(1000);    }
查看完整描述

3 回答

?
倚天杖

TA贡献1828条经验 获得超3个赞

您应该在属性本身上实现接口。此外,在调用 PropertyChanged 事件时,您应该使用事件的本地(作用域)句柄以避免竞争条件。


public class Money : INotifyPropertyChanged {

    double _currentMoney;


    public event PropertyChangedEventHandler PropertyChanged;

    public double CurrentMoney 

    { 

         get => _currentMoney;

         set

         {

             _currentMoney = value;

             OnPropertyChanged();

         }

    }


    public Money() => CurrentMoney = 1000;


    public int addMoney(double count) {

        CurrentMoney += count;

        return 1;

    }       


    public int subMoney(double count) {

        CurrentMoney -= count;

        if (CurrentMoney < 0) { return 100; }

        return 1;

    }


    public void OnPropertyChanged([CallerMemberName] string propertyName = null) 

    {

        var handle = PropertyChanged;

        handle?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    }


}

编辑:为了节省一些打字时间,您还可以创建一个 ViewModelBase 类来处理较小的细节。


public abstract class ViewModelBase : INotifyPropertyChanged, IDisposable

{

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string propertyName = null) 

    {

        var handle = PropertyChanged;

        handle?.Invoke(this, new PropertyChangedEventArgs(propertyName));

    }

    public virtual void Dispose() => PropertyChanged = null;

}

然后在实现 viewModel 类时,只需继承自 base(但仍会通知属性更改)。


public class MyClass : ViewModelBase

{

    string _myField;

    public string MyProperty

    {

        get => _myField;

        set

        {

            _myField = value;

            OnPropertyChanged();

        } 

    }

}

注意:实际错误来自 [CallerMemberName] 属性并从另一个方法中调用该方法。您可以传入属性名称作为参数,也可以使用属性本身的方法,而无需指定属性名称。


查看完整回答
反对 回复 2022-12-24
?
皈依舞

TA贡献1851条经验 获得超3个赞

您需要传递修改后的道具名称

NotifyPropertyChanged("CurrentMoney");


查看完整回答
反对 回复 2022-12-24
?
烙印99

TA贡献1829条经验 获得超13个赞

NotifyPropertyChanged 将 propertyName 作为参数。默认值为空。

private void NotifyPropertyChanged([CallerMemberName] string propertyName = null) {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

如果您想在 ui 上查看对“propertyName”的更改,可以使用 NotifyPropertyChanged("propertyName")。

对于您的示例,propertyName 是“CurrentMoney”


查看完整回答
反对 回复 2022-12-24
  • 3 回答
  • 0 关注
  • 140 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信