WPF使用MVVM实现UserControl2修改模型属性后同步更新到UserControl1
问题核心原因
你当前的代码存在两个核心问题导致属性变更无法同步:
- 你的
IPersonModel实现类没有实现INotifyPropertyChanged接口(或继承Caliburn.Micro的PropertyChangedBase),无法在自身属性值变更时对外发出通知 UserControl1ViewModel没有监听底层IPersonModel实例的属性变更事件,所以当UserControl2修改了Model的值后,UserControl1ViewModel不知道需要触发自身的UI更新通知
解决步骤
步骤1:完善PersonModel实现类,支持属性变更通知
确保你的IPersonModel实现类继承PropertyChangedBase,属性变更时触发通知:
public class PersonModel : PropertyChangedBase, IPersonModel { private string _firstName; public string FirstName { get => _firstName; set { _firstName = value; NotifyOfPropertyChange(() => FirstName); } } private string _lastName; public string LastName { get => _lastName; set { _lastName = value; NotifyOfPropertyChange(() => LastName); } } public string FullName => $"{FirstName} {LastName}"; }
步骤2:修改UserControl1ViewModel,监听Model属性变更
监听底层Model的属性变更事件,同步触发自身的UI更新通知,同时补全属性set方法的Model值回写逻辑:
public class UserControl1ViewModel : PropertyChangedBase { private IPersonModel Model; public UserControl1ViewModel(IPersonModel model) { Model = model; // 绑定Model的属性变更事件 Model.PropertyChanged += OnModelPropertyChanged; } private void OnModelPropertyChanged(object sender, PropertyChangedEventArgs e) { if (e.PropertyName == nameof(IPersonModel.FirstName)) { NotifyOfPropertyChange(() => FirstName); NotifyOfPropertyChange(() => FullName); } else if (e.PropertyName == nameof(IPersonModel.LastName)) { NotifyOfPropertyChange(() => LastName); NotifyOfPropertyChange(() => FullName); } } public string FirstName { get => Model.FirstName; set { Model.FirstName = value; NotifyOfPropertyChange(() => FirstName); NotifyOfPropertyChange(() => FullName); } } public string LastName { get => Model.LastName; set { Model.LastName = value; NotifyOfPropertyChange(() => LastName); NotifyOfPropertyChange(() => FullName); } } public string FullName => $"{FirstName} {LastName}"; // 释放资源时移除事件绑定,避免内存泄漏 ~UserControl1ViewModel() { Model.PropertyChanged -= OnModelPropertyChanged; } }
简化实现方案(可选)
如果你的ViewModel不需要对属性做额外业务逻辑处理,可以直接暴露Model对象,不需要手动包一层属性,代码更简洁:
- 修改UserControl1ViewModel:
public class UserControl1ViewModel : PropertyChangedBase { public IPersonModel Model { get; } public UserControl1ViewModel(IPersonModel model) { Model = model; } }
- 修改UserControl1的视图绑定:
<StackPanel Margin="10"> <TextBlock Text="{Binding Model.FirstName}" Margin="5"/> <TextBlock Text="{Binding Model.LastName}" Margin="5"/> <TextBlock Text="{Binding Model.FullName}" Margin="5"/> </StackPanel>
只要Model本身实现了属性变更通知,两个用户控件的绑定会自动同步。
内容的提问来源于stack exchange,提问作者Sajju Thambi
相关产品推荐
相关产品推荐

