WinForm MVVM中Model的INotifyPropertyChanged为何无法即时更新View?
WinForm MVVM属性绑定问题解决
问题场景
在WinForm简易MVVM架构中,ViewModel和Model均实现INotifyPropertyChanged接口:
- 文本框绑定ViewModel的
b属性,通过按钮点击修改,功能正常。 - 文本框绑定ViewModel的
a属性(该属性映射Model的a),点击按钮触发Model内方法修改a,Model的PropertyChanged事件正确触发,但文本框不更新;只有当b属性变更时,a的文本框才会同步更新。
问题根源
ViewModel监听Model的PropertyChanged事件时,传递了错误的属性名称:
private void Model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { NotifyPropertyChanged(nameof(e.PropertyName)); // 错误:此处传递的是字符串"PropertyName",而非实际变更的属性名"a" }
nameof(e.PropertyName)返回的是成员名称"PropertyName",而非e.PropertyName存储的实际属性名"a"。View绑定的是ViewModel的a属性,由于事件传递的属性名不匹配,因此不会触发文本框更新;只有当b属性变更时,View刷新绑定上下文才会顺带更新a的显示。
修正方案
修改ViewModel中的Model_PropertyChanged方法,直接传递Model变更的属性名:
private void Model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { NotifyPropertyChanged(e.PropertyName); }
完整修正后的ViewModel代码
public class TestPropertyChangedVM : INotifyPropertyChanged { TestPropertyChanged Model; public TestPropertyChangedVM() { Model = new TestPropertyChanged(); Model.PropertyChanged += Model_PropertyChanged; } private void Model_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) { NotifyPropertyChanged(e.PropertyName); // 修正:传递正确的属性名 } protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "") { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } public event PropertyChangedEventHandler PropertyChanged; public int a { get { return Model.a; } set { Model.a = value; NotifyPropertyChanged(); } } private int _b; public int b { get { return _b; } set { _b = value; NotifyPropertyChanged(); } } public void CmdIncrementA() { Model.CmdIncrementA(); } public void CmdIncrementB() { b++; } }
验证
修改后,当点击按钮触发Model的a属性递增时,ViewModel会正确触发PropertyChanged事件并传递属性名"a",View会立即更新对应的文本框显示。
内容的提问来源于stack exchange,提问作者postcreator
相关产品推荐
相关产品推荐

