C# 如何在ViewModel中订阅PropertyChanged事件?
我将核心功能封装在C# 如何在ViewModel中订阅PropertyChanged事件?,c#,mvvm,inotifypropertychanged,C#,Mvvm,Inotifypropertychanged,我将核心功能封装在ViewModelBase 现在我想看看ViewModelBase何时引发PropertyChanged事件并对其进行操作。例如,当ViewModelBase上的一个属性发生更改时-我想更改ViewModel上的属性 我如何做到这一点 public class MaintainGroupViewModel : BaseViewModel<MEMGroup> { public abstract class BaseViewModel<T> :
ViewModelBase
现在我想看看ViewModelBase何时引发PropertyChanged事件并对其进行操作。例如,当ViewModelBase上的一个属性发生更改时-我想更改ViewModel上的属性
我如何做到这一点
public class MaintainGroupViewModel : BaseViewModel<MEMGroup>
{
public abstract class BaseViewModel<T> : NotificationObject, INavigationAware
where T : Entity
{
公共类MaintainGroupViewModel:BaseViewModel
{
公共抽象类BaseViewModel:NotificationObject,INavigationAware
其中T:实体
{
如果您的
BaseViewModel
实现了以下功能,则可以使用订阅属性更改的直接方式:
PropertyChanged += (obj, args) =>
{ System.Console.WriteLine("Property " + args.PropertyName + " changed"); }
如果没有,那么它必须是一个DependencyObject
,并且您的属性必须是dependencProperties
(这可能是一种更复杂的方式)
描述如何订阅
DependencyProperty
更改。我通常使用register来注册类构造函数中的PropertyChanged
事件
public MyViewModel()
{
this.PropertyChanged += MyViewModel_PropertyChanged;
}
我的PropertyChanged事件处理程序如下所示:
void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case "SomeProperty":
// Do something
break;
}
}
我担心的是,您正在有效地将派生类中的属性“手动绑定”(bad)到基类上的值(也是bad)。使用继承的全部意义在于派生类可以访问基类中的内容。使用
受保护的修饰符指示内容应仅可由派生类访问
我建议采用(可能)更正确的方法:
基类:
protected virtual void OnMyValueChanged() { }
派生类:
protected override void OnMyValueChanged() { /* respond here */ }
真的,在你正在编写的类的基类中订阅一个事件似乎有着难以置信的倒退——如果你要围绕自己创作,那么使用继承而不是合成有什么意义呢?你实际上是在要求一个对象告诉自己什么时候发生了什么事情。你应该使用方法调用来实现这一点。
“当ViewModelBase上的一个属性发生更改时-我想更改ViewModel上的属性”,…它们是同一个对象!您的NotificationObject
是否实现了INotifyPropertyChanged
接口?如果是,则是基本事件订阅。如果不是,则应实现INotifyPropertyChanged
。是的,它确实有气味:)我的场景是这样的……我有基本功能,但在这种特定情况下当一些基本数据发生更改时,我想重新排列ViewModel上的一些数据。基类维护主数据实体(比如Customer)当客户发生变化时,我想更新更多的UI。我仍然建议使用方法而不是事件,并且在必要时使用组合而不是继承:创建一个包含基本ViewModel的新对象。否则,每个人仍然可以访问基本ViewModel的“基本”功能,而实际上您似乎正在修改它,所以派生类不适合。也许方法是一种方法。另一个例子。基类维护“状态”我的数据输入表单。如NEW、EDIT、ADD。大量UI绑定到此状态。在我的VM中,我也想知道此状态更改。我可以在StateChange上创建方法,也可以订阅PropertyChanged。您是否认为需要重新组合或仅创建方法?方法可能更“干净”要了解哪些功能应该属于基本视图模型,尤其是像OnStateChange这样的通用功能。你能再举一个例子吗?:)我明白了。基本上,订阅自己的事件是一种代码味道。重写OnStateChange并调用base.OnStateChange是处理这种情况的正确方法。这两种方法都可以实现相同的功能ty.在处理过程中,是否有任何方法可以去除“魔法字符串”。(我不使用C#6)@Marshal我不确定,那又如何?我认为这是一个很好的解决方案,而且是可以测试的。感谢您指出这篇文章。@Rachel:您认为如何使用这种技术来避免“为级联只读属性而重复RaiseProperty更改”()?@Tom我想没关系。给你留了一个问题的答案:)