如何实现 chained/proxied 数据绑定
How to implement chained/proxied databindings
我在我的 mvvm wpf 应用程序中遇到了这个问题,我想在其中创建 proxied/chained 数据绑定。
我的 ModelViewController 看起来像这样:
public class ListViewModel
{
public ObservableCollection<Contact> GridData { get; private set; }
public ObservableCollection<Contact> SelectedEntities { get; private set; }
public bool IsSingeselect { get { return SelectedEntities.Count == 1; } }
public bool IsMultiSelect { get { return SelectedEntities.Count > 0; } }
public ObservableCollection<MenuComandModel> ContextMenuItems { get; private set; }
}
GridData
和 SelectedEntities
绑定到数据网格并且工作起来很有魅力。我正在使用 ContextMenuItems
集合为数据网格上下文菜单创建 BarButtonItems,这非常有效。 MenuComandModel
class 有一个 Enabled
属性,我想将它绑定到 IsSingeselect
或 IsMultiSelect
属性到 BarButtonItems
成员 IsEnabled
。我该如何存档?
由于您使用的是 DevExpress,因此您可以享受 DevExpress MVVM Framework and their POCO-ViewModels 的所有优势:
using DevExpress.Mvvm.POCO;
//...
public class ListViewModel {
public ObservableCollection<Contact> GridData { get; private set; }
// mark the SelectedEntities property as virtual to be notified on initializing/replacing
public virtual ObservableCollection<Contact> SelectedEntities { get; private set; }
// unsubscribe the CollectionChanged event in changing-callback
protected void OnSelectedEntitiesChanging() {
if(SelectedEntities != null)
SelectedEntities.CollectionChanged -= SelectedEntities_CollectionChanged;
}
// subscribe the CollectionChanged event in changed-callback
protected void OnSelectedEntitiesChanged() {
if(SelectedEntities != null)
SelectedEntities.CollectionChanged += SelectedEntities_CollectionChanged;
UpdateSelectedEntitiesDependencies();
}
void UpdateSelectedEntitiesDependencies() {
// Raise INPC for dependent properties
this.RaisePropertyChanged(x => x.IsSingeselect);
this.RaisePropertyChanged(x => x.IsMultiSelect);
// Raise INPC for dependent properties of child ViewModels
foreach(var item in ContextMenuItems)
item.RaisePropertyChanged(x => x.Enabled);
}
void SelectedEntities_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
if(e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Reset)
UpdateSelectedEntitiesDependencies();
}
public bool IsSingeselect { get { return SelectedEntities.Count == 1; } }
public bool IsMultiSelect { get { return SelectedEntities.Count > 0; } }
public ObservableCollection<MenuComandViewModel> ContextMenuItems { get; private set; }
}
public class MenuComandViewModel {
public bool Enabled {
get {
var parentViewModel = this.GetParentViewModel<ListViewModel>();
return parentViewModel.IsMultiSelect; // Some implementation
}
}
}
然后您可以使用MVVM Support in DXBars, DXRibbon and GalleryControl帮助文章中描述的方法绑定您禁止的项目到 ContextMenuItems 集合。
我在我的 mvvm wpf 应用程序中遇到了这个问题,我想在其中创建 proxied/chained 数据绑定。
我的 ModelViewController 看起来像这样:
public class ListViewModel
{
public ObservableCollection<Contact> GridData { get; private set; }
public ObservableCollection<Contact> SelectedEntities { get; private set; }
public bool IsSingeselect { get { return SelectedEntities.Count == 1; } }
public bool IsMultiSelect { get { return SelectedEntities.Count > 0; } }
public ObservableCollection<MenuComandModel> ContextMenuItems { get; private set; }
}
GridData
和 SelectedEntities
绑定到数据网格并且工作起来很有魅力。我正在使用 ContextMenuItems
集合为数据网格上下文菜单创建 BarButtonItems,这非常有效。 MenuComandModel
class 有一个 Enabled
属性,我想将它绑定到 IsSingeselect
或 IsMultiSelect
属性到 BarButtonItems
成员 IsEnabled
。我该如何存档?
由于您使用的是 DevExpress,因此您可以享受 DevExpress MVVM Framework and their POCO-ViewModels 的所有优势:
using DevExpress.Mvvm.POCO;
//...
public class ListViewModel {
public ObservableCollection<Contact> GridData { get; private set; }
// mark the SelectedEntities property as virtual to be notified on initializing/replacing
public virtual ObservableCollection<Contact> SelectedEntities { get; private set; }
// unsubscribe the CollectionChanged event in changing-callback
protected void OnSelectedEntitiesChanging() {
if(SelectedEntities != null)
SelectedEntities.CollectionChanged -= SelectedEntities_CollectionChanged;
}
// subscribe the CollectionChanged event in changed-callback
protected void OnSelectedEntitiesChanged() {
if(SelectedEntities != null)
SelectedEntities.CollectionChanged += SelectedEntities_CollectionChanged;
UpdateSelectedEntitiesDependencies();
}
void UpdateSelectedEntitiesDependencies() {
// Raise INPC for dependent properties
this.RaisePropertyChanged(x => x.IsSingeselect);
this.RaisePropertyChanged(x => x.IsMultiSelect);
// Raise INPC for dependent properties of child ViewModels
foreach(var item in ContextMenuItems)
item.RaisePropertyChanged(x => x.Enabled);
}
void SelectedEntities_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) {
if(e.Action == NotifyCollectionChangedAction.Add || e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Reset)
UpdateSelectedEntitiesDependencies();
}
public bool IsSingeselect { get { return SelectedEntities.Count == 1; } }
public bool IsMultiSelect { get { return SelectedEntities.Count > 0; } }
public ObservableCollection<MenuComandViewModel> ContextMenuItems { get; private set; }
}
public class MenuComandViewModel {
public bool Enabled {
get {
var parentViewModel = this.GetParentViewModel<ListViewModel>();
return parentViewModel.IsMultiSelect; // Some implementation
}
}
}
然后您可以使用MVVM Support in DXBars, DXRibbon and GalleryControl帮助文章中描述的方法绑定您禁止的项目到 ContextMenuItems 集合。