gpt4 book ai didi

c# - MVVM INotifyPropertyChanged 与基类 PropertyChange 冲突

转载 作者:行者123 更新时间:2023-11-30 19:30:27 24 4
gpt4 key购买 nike

我对 MVVM 比较陌生,我想了解 INotifyPropertyChanged 接口(interface)的工作原理以及如何在我的模型中实现它。我决定采用的方法是在我的每个业务对象类中实现它。
该方法的问题是,当我将 View 绑定(bind)到基类中的属性时,该基类中的 PropertyChanged 事件永远不会被初始化(为空),因此 View 不会刷新该元素的数据我的模型改变了。我能够通过下面的示例重现该问题。

我有一个 Person 基类:

 public class Person : INotifyPropertyChanged
{
#region INotifyProperty

public event PropertyChangedEventHandler PropertyChanged;

public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion

public String Name
{
get
{
return _name;
}
set
{
_name = value;
RaisePropertyChanged("Name");
}
}
private String _name;
}

我有一个从我的 Person 基类继承的 Employee 类:

 public class Employee : Person,INotifyPropertyChanged
{
#region INotifyProperty

public event PropertyChangedEventHandler PropertyChanged;

public void RaisePropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion


public String EmployeeID
{
get
{
return _employeeId;
}
set
{
_employeeId = value;
RaisePropertyChanged("EmployeeID");
}
}
private String _employeeId;
}

这是我的 View 模型:

 public class ViewModel : ViewModelBase<ViewModel>
{
private Employee _employee;

public ViewModel()
{
ChangeModelCommand = new RelayCommand(param=>this.ChangeModel() , param=>this.CanChangeModel);
Employee = new Employee()
{
Name = "BOB",EmployeeID = "1234"
};
}

public ICommand ChangeModelCommand { get; set; }


public Employee Employee
{
get
{
return _employee;
}
set
{
this._employee = value;
NotifyPropertyChanged(m=>m.Employee);
}
}

public void ChangeModel()
{
MessageBox.Show("CHANGING MODEL");
this.Employee.Name = "MIKE";
this.Employee.EmployeeID = "5678";
}
public bool CanChangeModel
{
get{ return true;}
}
}

最后是我的观点:

<Window.Resources>
<MVVM_NotificationTest:ViewModel x:Key="Model"></MVVM_NotificationTest:ViewModel>
</Window.Resources>
<Grid DataContext="{StaticResource Model}">
<StackPanel>
<Label Content="Employee Name"/>
<TextBox Text="{Binding Path=Employee.Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Label Content="Employee ID"/>
<TextBox Text="{Binding Path=Employee.EmployeeID,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="Change Model" Height="30" Width="100" Margin="5" Command="{Binding Path=ChangeModelCommand}"/>
</StackPanel>
</Grid>

在这个例子中,我在 VM 构造函数中初始化了我的 Employee VM 属性,然后我有一个命令来修改 EmployeeID(来自 Employee 类)和 Name(来自 Person 类)。但是,View 中唯一更新的 UI 元素是 EmployeeID 而不是 Name(我希望 Bob 更新为 Mike)。

调试时我发现我的基础中的 PropertyChanged 事件始终为 null类(人)。我还注意到,当我从我的 Employee 类中删除整个 #INotifyProperty 区域时,一切正常,因为它使用的是 Base Type 事件和方法。

我遇到的问题是我当前的所有模型类显式实现 INotifyPropertyChanged。它们都定义了一个 PropertyChanged 事件并实现了 RaisePropertyChanged 方法,这显然会影响我在 MVVM 应用程序中的绑定(bind)。

最后,我想澄清一下,我不想将我的模型属性包装在我的 ViewModel 中,并且依赖VM INPC机制。我想使用我的模型 INPC 实现,而不必根据我是否从基类型继承来有条件地删除 INPC 实现。

总之,我想知道在我的深层分层模型中实现 INPC 的最佳方法是什么,这样继承就不会像我们在这个例子中看到的那样破坏 PropertyEvent 传播,这样我的独立类也可以自给自足。任何想法或建议将不胜感激:)

最佳答案

简单地使 RaisePropertyChanged protected 并将其移动到基类中。目前你会有很多不必要的重复。

像这样:

protected virtual void RaisePropertyChanged(string propertyName);

许多 MVVM 框架都为您提供了这一点。例如 PRISM 有一个 NotificationObject ViewModel 基类。

关于c# - MVVM INotifyPropertyChanged 与基类 PropertyChange 冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9053764/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com