MVVM和INotifyPropertyChanged问题
我有一个MVVM设计的大问题。 我试图捕获我的内部嵌套对象的每个PropertyChanged,包括他们的嵌套对象的更多属性,在我的ViewModel中,但我不知道如何做到这一点。
这是我的结构:
class MyVM { public MyVM() { this.SomeData = new SomeData(); this.SomeData.NestedObj = new MyNestedDat(); this.SomeData.Str = "This tiggers propertychanged inside MyDat class"; // this triggers propertychanged event inside MyNestedDat class this.SomeData.NestedObj.Num = 123; } // and here should be a method where i catch all possibe propertychanges from my nested objets and their nested objets, how do i do that? public MyDat SomeData { get; set; } } class MyDat : INotifyPropertyChanged { private string str; public string Str; { get { return this.str;} set { this.str = value; this.PropertyChanged(this, "Str"); } } publicMyNestedDat NestedObj { get; set; } } class MyNestedDat : INotifyPropertyChanged { private int num; public int Num { get{ return this.num;} set { this.num = value; this.PropertyChanged(this, "Num"); } } }
我如何让它工作? 我真的很无知从哪里开始。
MyNestedDat类抛出PropertyChanged,MyDat类抛出propertychanged,我想在我的viewmodel中捕获它们。 我怎样才能做到这一点?
在我看来,你提出的问题有一些概念上的错误。 想象一下,你得到的解决方案适合你的场景(你很满意)并考虑以下内容:
这应该引起警惕,目前的方法不是正确的道路。
你需要的是一种以松散耦合的方式在viewModel之间提供通信的方法,这样你的viewModels甚至不需要知道彼此的存在。 这样做的好处在于,这也适用于其他情况,而不仅仅是财产变化。
对于属性更改事件的情况,一个viewModel想要知道什么时候发生 (它可能是属性更改事件以外的事情,请记住)。 这意味着另一个viewModel需要某种方式来说“嘿,属性已经改变”(或“我的状态已经改变”,“数据库调用已经完成”等)。
现在在C#中你可以提供提供此function的事件….除了,现在你的对象知道了彼此,这给你留下了你以前遇到的同样问题。
要解决这个问题,你需要另一个对象,一个中介(在这个例子中称之为Messenger
),其唯一目的是处理在对象之间传递的消息,这样他们就可以生活在彼此的无知之中。
一般的想法是这样的。 在提供通知的viewModel中,您可能会执行以下操作:
public string MyProp { get { return _myProp; } set { _mProp = value; OnPropertyChanged("MyProp"); Messenger.PostMessage(new VMChangedMessage { ViewModel = this, PropertyName = "MyProp" }); } }
在对事件感兴趣的viewModel中,您可能会执行以下操作:
public class ViewModel2 { public ViewModel2() { Messenger.Subscribe(handleMessage); } private void handleMessage(VMChangedMessage msg) { // Do something with the information here... } }
请注意,两个viewModels永远不会互相引用。 他们现在松散耦合。
有许多预先存在的实现已经可用,并且创建自己的实现并不困难(信使基本上保留对特定消息感兴趣的对象列表,并在需要通知感兴趣的各方时迭代列表) 。 有些事情可以用不同的方式实现(有些实现只是传递字符串消息而不是将信息封装在对象中,有些实现自动清理观察者)。
我建议使用包含信使类的Josh Smiths(优秀) MVVM Foundation 。 它也是开源的,所以你可以看到它是如何工作的。
PropertyName
对PropertyName
应包含的内容没有明确的约束。
有关嵌套(子)对象,请参阅订阅INotifyPropertyChanged 。
这是一个例子:
class A : BaseObjectImplementingINotifyPropertyChanged { private string m_name; public string Name { get { return m_name; } set { if(m_name != value) { m_name = value; RaisePropertyChanged("Name"); } } } } class B : BaseObjectImplementingINotifyPropertyChanged { private A m_a; public AA { get { return m_a; } set { if(m_a != value) { if(m_a != null) m_a.PropertyChanged -= OnAPropertyChanged; m_a = value; if(m_a != null) m_a.PropertyChanged += OnAPropertyChanged; RaisePropertyChanged("A"); } } } private void OnAPropertyChanged(object sender, PropertyChangedEventArgs e) { RaisePropertyChanged("A." + e.PropertyName); } } B b = new B(); b.PropertyChanged += (s, e) => { Console.WriteLine(e.PropertyName); }; bAName = "Blah"; // Will print "A.Name"
这里最好的做法是分离Model和ViewModel的想法。
通过使ViewModel
对象比Model
更平坦,您可以避免这种情况。 使用Automapper等自动映射工具,您可以将Model
映射到ViewModel
,反之亦然。
https://github.com/AutoMapper/AutoMapper/wiki/Flattening
上述就是C#学习教程:MVVM和INotifyPropertyChanged问题分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
class MyDatViewModel : INotifyPropertyChanged { public string Str { // ... Get Set } public int NestedObjNum { // ... Get set } } // Configure AutoMapper Mapper.CreateMap(); // Perform mapping MyDatViewModel viewModel = Mapper.Map(someData);
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/986777.html