MVVM 集合的ViewModel
来源:互联网 发布:看不见的客人 知乎 编辑:程序博客网 时间:2024/04/29 18:40
下面分享一个自己在工作中实际用到的关于集合处理的ViewModel。
我们都知道,WPF中,有关于Combobox、List以及DataGrid等等的控件,其属性DataSource基本上都会与ObservableCollection<T>绑定。下面给出一个我自己的解决方案,以供参考。
主要实现的功能有:提供数据源、双击、选项改变、添加数据项、移除数据项等
UML
接口 ICollectionViewModel<T>
属性:
接口中的PageViewModel是分页的实现,此篇不分析和提供该类的实现方式!
Collection是对外提供的集合类
DoubleClickCommand是当双击选项时触发的命令
SelectedIndex是选中的索引
SelectedItem是选中的项
SelectedIsNull表示选中项是否为空
方法:
Add(T item)表示向集合中添加项
Clear():表示清空集合
GetIndex(Func<T, bool> predicate):表示根据条件获取该项在集合中所在的索引值
GetItem(Func<T, bool> predicate):根据条件获取项
Remove(T item):移除某项
RemoveAt(int index):移除指定索引项
事件:
CollectionChanged:参考ObservableCollection<T>中的CollectionChanged
DoubleClick:双击命令触发的事件
SelectedCheanged:选中项发生改变
实现类 CollectionViewModel
实现代码:
接口实现代码
/// <summary> /// Collection ViewModel Interface. /// </summary> /// <typeparam name="T"> /// </typeparam> public interface ICollectionViewModel<T> { /// <summary> /// 选中项发生改变. /// </summary> event EventHandler SelectedChanged; /// <summary> /// 双击项 /// </summary> event EventHandler DoubleClick; /// <summary> /// 集合改变. /// </summary> event NotifyCollectionChangedEventHandler CollectionChanged; /// <summary> /// 双击命令. /// </summary> ICommand DoubleClickCommand { get; } /// <summary> /// 数据源. /// </summary> ReadOnlyObservableCollection<T> Collection { get; } /// <summary> /// 选中项. /// </summary> T SelectedItem { get; set; } /// <summary> /// 选中项索引. /// </summary> int SelectedIndex { get; set; } /// <summary> /// 选中项是否为空. /// </summary> bool SelectedIsNull { get; } /// <summary> /// 根据条件获取索引. /// </summary> /// <param name="predicate"> /// The predicate. /// </param> /// <returns> /// The <see cref="int"/>. /// </returns> int GetIndex(Func<T, bool> predicate); /// <summary> /// 根据条件获取项. /// </summary> /// <param name="predicate"> /// The predicate. /// </param> /// <returns> /// The <see cref="T"/>. /// </returns> T GetItem(Func<T, bool> predicate); /// <summary> /// 添加项. /// </summary> /// <param name="item"> /// The item. /// </param> void Add(T item); /// <summary> /// 清空集合. /// </summary> void Clear(); /// <summary> /// 移除项. /// </summary> /// <param name="item"> /// The item. /// </param> void Remove(T item); /// <summary> /// 移除制定索引项. /// </summary> /// <param name="index"> /// The index. /// </param> void RemoveAt(int index); /// <summary> /// 转换为List. /// </summary> /// <returns> /// The <see> /// <cref>IList</cref> /// </see> /// . /// </returns> IList<T> ToList(); }
类实现代码
/// <summary> /// The Collection ViewModel实现. /// </summary> /// <typeparam name="T"> /// <tag>泛型</tag> /// </typeparam> public class CollectionViewModel<T> : ViewModelBase, ICollectionViewModel<T> { /// <summary> /// The seletected item. /// </summary> private T seletectedItem; /// <summary> /// The selected index. /// </summary> private int selectedIndex; /// <summary> /// Initializes a new instance of the <see cref="CollectionViewModel{T}"/> class. /// </summary> public CollectionViewModel() { this.DoubleClickCommand = new RelayCommand( () => { if (DoubleClick != null) { DoubleClick(this, new EventArgs()); } }); this.ListCollection = new ObservableCollection<T>(); this.Collection = new ReadOnlyObservableCollection<T>(this.ListCollection); this.ListCollection.CollectionChanged += (o, e) => this.OnCollectionChanged(e); } /// <summary> /// The selected changed. /// </summary> public event EventHandler SelectedChanged; /// <summary> /// The double click. /// </summary> public event EventHandler DoubleClick; /// <summary> /// The collection changed. /// </summary> public event NotifyCollectionChangedEventHandler CollectionChanged; /// <summary> /// Gets the double click command. /// </summary> public ICommand DoubleClickCommand { get; private set; } /// <summary> /// Gets or sets the page view model. /// </summary> public IListPageViewModel PageViewModel { get; set; } /// <summary> /// Gets a value indicating whether selected is null. /// </summary> public bool SelectedIsNull { get { return null == this.SelectedItem; } } /// <summary> /// Gets or sets the selected index. /// </summary> public int SelectedIndex { get { return this.selectedIndex; } set { this.selectedIndex = value; this.RaisePropertyChanged("SelectedIndex"); } } /// <summary> /// Gets or sets the selected item. /// </summary> public T SelectedItem { get { return this.seletectedItem; } set { this.seletectedItem = value; if (!this.SelectedIsNull && this.SelectedChanged != null) { this.SelectedChanged(this, new EventArgs()); } this.RaisePropertyChanged("SelectedItem"); } } /// <summary> /// Gets the collection. /// </summary> public ReadOnlyObservableCollection<T> Collection { get; private set; } /// <summary> /// Gets the list collection. /// </summary> protected ObservableCollection<T> ListCollection { get; private set; } /// <summary> /// The add. /// </summary> /// <param name="item"> /// The item. /// </param> public void Add(T item) { this.ListCollection.Add(item); } /// <summary> /// The clear. /// </summary> public void Clear() { this.ListCollection.Clear(); } /// <summary> /// The get index. /// </summary> /// <param name="predicate"> /// The predicate. /// </param> /// <returns> /// The <see cref="int"/>. /// </returns> /// <exception cref="NullReferenceException"> /// </exception> public int GetIndex(Func<T, bool> predicate) { if (predicate == null) { throw new NullReferenceException("predicate is null"); } var index = this.ListCollection.Where(predicate) .Select(m => this.ListCollection.IndexOf(m)) .SingleOrDefault(); return index; } /// <summary> /// The get item. /// </summary> /// <param name="predicate"> /// The predicate. /// </param> /// <returns> /// The <see cref="T"/>. /// </returns> /// <exception cref="NullReferenceException"> /// </exception> public T GetItem(Func<T, bool> predicate) { if (predicate == null) { throw new NullReferenceException("predicate is null"); } var obj = this.ListCollection.SingleOrDefault(predicate); return obj; } /// <summary> /// The remove at. /// </summary> /// <param name="index"> /// The index. /// </param> public void RemoveAt(int index) { this.ListCollection.RemoveAt(index); } /// <summary> /// The to list. /// </summary> /// <returns> /// The <see cref="IList{T}"/>. /// </returns> public IList<T> ToList() { return this.ListCollection.ToList(); } /// <summary> /// The remove. /// </summary> /// <param name="item"> /// The item. /// </param> public void Remove(T item) { this.ListCollection.Remove(item); } /// <summary> /// The on collection changed. /// </summary> /// <param name="e"> /// The e. /// </param> protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e) { var handler = this.CollectionChanged; if (handler != null) { handler(this, e); } } }
通过实现代码可以看出,CollectionViewModel<T>主要提供了两个集合
public ReadOnlyObservableCollection<T> Collection { get; private set; }
和
protected ObservableCollection<T> ListCollection { get; private set; }
对于Collection,它是对外只读集合,也就是说,所以对集合的操作都必须通过CollectionViewModel类来实现,这样,我们就通过CollectionViewModel控制了集合的修改,防止了外部修改集合。
使用:
Combobox:
<ComboBox DataContext="{Binding FactoryRegulationCollectionVm, Mode=OneWay}" ItemsSource="{Binding Collection}" SelectedItem="{Binding SelectedItem, Mode=TwoWay}" DisplayMemberPath="FactoryRegulationName" />
DataGrid:此处的DataGrid提供了双击选项的功能
<DataGrid Grid.Row="2" BorderBrush="#D24726" BorderThickness="1" DataContext="{Binding ImageinfoCollectionViewModel}" ItemsSource="{Binding Collection}" SelectedItem="{Binding SelectedItem,Mode=TwoWay}" IsReadOnly="True" CanUserSortColumns="False" HorizontalAlignment="Center" AutoGenerateColumns="False" > <i:Interaction.Triggers> <!--双击事件绑定到命令--> <i:EventTrigger EventName="PreviewMouseDoubleClick"> <i:InvokeCommandAction Command="{Binding DoubleClickCommand}"></i:InvokeCommandAction> </i:EventTrigger> </i:Interaction.Triggers> <DataGrid.Columns> <DataGridTextColumn Header="{DynamicResource lang_SerialNumber}" Binding="{Binding rowID}" /> </DataGrid.Columns> </DataGrid>
未解决的问题:
1. 多选的问题,就是在DataGrid中,选中多个项,暂时没有想到比较好的解决方案。
2. 其他未使用到的。上面给出的处理方案都是在实际工作中遇到的,也许还有其他需要解决的,但是暂时还未遇到。
注:
1. 本人的ViewModel主要依靠的框架是 MVVM Light ,感兴趣的可以自行百度
2. 本人 QQ:351157970, 欢迎交流,一起讨论工作中遇到的问题
3. Demo代码:CollectionViewModel
3. Demo代码:CollectionViewModel
0 0
- MVVM 集合的ViewModel
- MVVM 模式 ViewModel
- Android MVVM ViewModel
- Silverlight + Model-View-ViewModel (MVVM)
- Silverlight + Model-View-ViewModel (MVVM)
- Model-View-ViewModel (MVVM) Explained
- 关于MVVM(Model-View-ViewModel)
- ZK Model-View-ViewModel (MVVM)
- 如何利用AOP简化MVVM中Model和ViewModel的设计
- 如何利用Interception简化MVVM中的Model和ViewModel的设计
- MVVM模式通过ViewModel实现view和model的低耦合
- MVVM模式通过ViewModel实现view和model的低耦合
- MVVM(Model-View-ViewModel)实例讲解
- MVVM(Model-View-ViewModel)实例讲解
- Silverligt MVVM (Model-View-ViewModel) : 简要说明
- Silverligt MVVM (Model-View-ViewModel) : 简要说明
- MVVM模式之:ViewModel Factory与注入
- MVVM 后台代码调用viewModel方法
- VC++MFC中在初始化窗口过程中不要过早使用GetWindowRect
- objective-c 继承机制 (从runtime的角度)
- 我最近正在复习表单验证这一块内容,有一些知识点实在是想不起来了,希望各位大神能帮我解决一下!
- android的生命周期
- 编程挑战-高校俱乐部-回文距离
- MVVM 集合的ViewModel
- 大江流日夜
- 三极管
- 【JS】JS的面向对象编程
- [MVC4]ASP.NET MVC4+EF5(Lambda/Linq)读取数据
- 从C看C++之(六)多态
- jre 与jdk的区别
- C语言scanf函数详细解释
- window下 UDP socket编程