如何在ViewModel层次结构中冒泡更改?
我的MainView.xaml包含我的SmartForm视图:
SmartForm视图加载ItemsControl
这是DataTypeViews的ObservableCollection:
List formFields = new List(); formFields.Add(new FormField { IdCode = "firstName", Label = "First Name", Value = "Jim" }); formFields.Add(new FormField { IdCode = "lastName", Label = "Last Name", Value = "Smith" }); formFields.Add(new FormField { IdCode = "address1", Label = "Address 1", Value = "123 North Ashton Rd." }); formFields.Add(new FormField { IdCode = "address2", Label = "Address 2", Value = "Box 23434" }); formFields.Add(new FormField { IdCode = "city", Label = "City", Value = "New Haven" }); formFields.Add(new FormField { IdCode = "state", Label = "State", Value = "NM" }); formFields.Add(new FormField { IdCode = "zip", Label = "Zip Code", Value = "34234" }); foreach (FormField formField in formFields) { DataTypeView dtv = new DataTypeView(); DataTypeViewModel dtvm = new DataTypeViewModel(formField); dtv.DataContext = dtvm; DataTypeViews.Add(dtv); }
每个视图显示构建表单的标签和文本框:
如何将DataTypeViewModel中发生的文本框更改冒泡到SmartFormViewModel中?
或者换句话说: 如果ViewModel A包含ViewModel B的集合,并且在ViewModel B中发生了更改,那么如何将该更改冒泡到ViewModel A?
您可以让父虚拟机连接到子虚拟机上的PropertyChanged事件。 这是一种PITA,用于跟踪已添加/删除的子项等,因此您可以考虑将子VM存储在ItemObservableCollection
:
public sealed class ItemObservableCollection : ObservableCollection where T : INotifyPropertyChanged { public event EventHandler> ItemPropertyChanged; protected override void InsertItem(int index, T item) { base.InsertItem(index, item); item.PropertyChanged += item_PropertyChanged; } protected override void RemoveItem(int index) { var item= this[index]; base.RemoveItem(index); item.PropertyChanged -= item_PropertyChanged; } protected override void ClearItems() { foreach (var item in this) { item.PropertyChanged -= item_PropertyChanged; } base.ClearItems(); } protected override void SetItem(int index, T item) { var oldItem = this[index]; oldItem.PropertyChanged -= item_PropertyChanged; base.SetItem(index, item); item.PropertyChanged -= item_PropertyChanged; } private void item_PropertyChanged(object sender, PropertyChangedEventArgs e) { OnItemPropertyChanged((T)sender, e.PropertyName); } private void OnItemPropertyChanged(T item, string propertyName) { ItemPropertyChanged.Raise(this, new ItemPropertyChangedEventArgs (item, propertyName)); } }
然后,您的父虚拟机可以通过以下方式监听子项的所有更改:
_formFields.ItemPropertyChanged += (s, e) => Foo();
我认为你应该使用你可以在这里阅读的中介模式。
基本上它是一个静态类,允许ViewModels(或任何类)相互通信并来回传递参数。
基本上,ViewModel A开始监听某种消息类型(例如ViewModelBChanged),并且只要该事件发生,ViewModelB只是通知任何正在监听此消息类型的人,它也可以传递它想要的任何信息。
这是调解员的骨架。
public static class MyMediator { public static void Register(Action
ViewModel A会这样做(可能在构造函数中):
MyMediator.Register(ProcessMessage,"ViewModelBChanged")
然后必须声明一个这样的函数:
void ProcessMessage(object args) { //Do some important stuff here }
只要想要告诉ViewModel A,ViewModel B就会调用它
MyMediator.NotifyColleagues("ViewModelBChanged",this);
中介类将负责调用viewModel A的回调函数。然后每个人都很高兴。
我个人喜欢把这些字符串消息值放在这样的静态类中
static class MediatorMessages { public static string ViewModelBChanged= "ViewModelBChanged"; }
这样你就可以做到以下(而不是上面的):
MyMediator.Register(ProcessMessage,MediatorMessages.ViewModelBChanged) MyMediator.NotifyColleagues(MediatorMessages.ViewModelBChanged,this);
如果这不清楚只是谷歌MVVM中介并点击你的心脏内容:)
非WPF方式是在DataTypeViewModel上创建静态事件。 这允许您在适当时(在属性设置器或属性更改处理程序中)从DataTypeViewModel触发事件。 当然,您还必须在SmartForm中注册事件的监听器(要求SmartForm了解DataTypeViewModel类型)。
或者,我认为您可以创建自己的自定义路由事件。
虽然肯特就在上面,但并非所有子视图模型的变化都与属性有关,有些可能比这更具语义性。 在这种情况下,实施责任链模式的变体可能是一个很好的选择。
简而言之
“master”处理程序不必是Singleton,其注册表可以依赖于父视图模型本身。
希望它足够清楚(抱歉不放代码)
我通过将ViewModel本身传递到其中包含的ViewModel中来解决这个问题, 这是一个演示如何完成的演示 。
上述就是C#学习教程:如何在ViewModel层次结构中冒泡更改?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1009133.html