【问题标题】:Invoking PropertyChanged from a Method to update properties从方法调用 PropertyChanged 以更新属性
【发布时间】:2019-10-07 10:11:39
【问题描述】:

我想弄清楚如何使用 ViewModel 更新我的布尔属性 INotifyPropertyChanged?

基本上在我的 ViewModel 中,我传入一个字符串列表。每个布尔属性检查列表以查看是否有 字符串值存在。

现在在我的软件生命周期中,列表将得到更新,而我想更新每个属性 使用 INotifyPropertyChanged。

我的问题是如何从 AddToList 方法调用 INotifyPropertyChanged?正在为此使用一种方法 方向正确吗?

public class ViewModel : INotifyPropertyChanged
{   
    private List<string> _listOfStrings;

    public ViewModel(List<string> ListOfStrings)
    {   
        _listOfStrings = ListOfStrings;     
    }

    public bool EnableProperty1 => _listOfStrings.Any(x => x == "Test1");
    public bool EnableProperty2 => _listOfStrings.Any(x => x == "Test2");
    public bool EnableProperty3 => _listOfStrings.Any(x => x == "Test3");
    public bool EnableProperty4 => _listOfStrings.Any(x => x == "Test4");

    public void AddToList(string value)
    {
        _listOfStrings.Add(financialProductType);
        // Should I call the OnPropertyChanged here     
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

【问题讨论】:

    标签: c# viewmodel mvp inotifypropertychanged


    【解决方案1】:

    这里最简单的做法是在AddString 方法中手动调用OnPropertyChanged

    public void AddToList(string value)
    {
        _listOfStrings.Add(financialProductType);
        OnPropertyChanged("EnableProperty1");
        OnPropertyChanged("EnableProperty2");
        // etc
    }
    

    如果你不太可能改变班级,这很好。如果您添加另一个根据 _listOfStrings 计算的属性,则需要在此处添加 OnPropertyChanged 调用。

    使用ObservableCollection 并没有真正的帮助,因为您已经知道列表何时更改 (AddToList),而且您仍然必须触发所有 OnPropertyChanged 方法。

    【讨论】:

    • 感谢您的解决方案。是否不建议定义 list 属性并在将更新属性的列表属性的设置器中使用 OnPropertyChanged ?还是我还需要更新属性?
    • @KJSR 它们仍然是列表中的计算值,因此它们也需要自己的更新。
    • 好的,谢谢。只是我可能不得不添加更多属性并且不喜欢我每次都需要执行 OnPropertyChanged("propertyName") 的事实:(
    • 这样做需要为每个属性调用 OnPropertyChanged。
    • 是的,这是保持简单的方法之一,直到它成为一个维护问题,然后让它变得更复杂,情况。
    【解决方案2】:

    据我所知,您的实现中缺少两件事:

    1. 您应该使用ObservableCollection 而不是List。顾名思义,前者可以通过视图observed(通知其变化)。
    2. 您需要将控件绑定到公共 ObservableCollection 并在每次分配/更改集合的值时调用 OnPropertyChanged。像这样:
    private ObservableCollection<string> _myList;
    // your control should bind to this property
    public ObservableCollection<string> MyList
    {
        get => return _myList;
        set
        {
            // assign a new value to the list
            _myList = value;
            // notify view about the change
            OnPropertiyChanged(nameof(MyList));
        }
    }
    
    
    // some logic in your view model
    string newValue = "newValue";
    _myList.Add(newValue );
    OnPropertyCHanged(nameof(MyList));
    

    希望这有帮助吗?

    【讨论】:

    • 感谢您的解决方案。我假设我仍然需要更新各个属性?
    • 当然,我的朋友。每当您更改属性时,只需调用“OnPropertyChanged”即可通知视图中的绑定控件您的属性更改。
    猜你喜欢
    • 2023-03-23
    • 2019-02-04
    • 1970-01-01
    • 2019-07-09
    • 2019-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-15
    相关资源
    最近更新 更多