IList与IList[T],自定义接口IActionList
2012-08-28 14:45 by 旦旦, 143 阅读, 1 评论, 收藏, 编辑
WPF DataGriw采用编辑模式,用户可以双击最尾的空白行从而新加一条记录.也可以选择行记录后按键盘Del键来删除选择的记录,做完一系列的操作后一次性把数据都保存到远程数据库中.那在MVVM中Ui和后台是分离的.不能直接知道那样那数据是新加\还是修改\有那些数据是被删除的了.那当前操作的集合表面保存的数据就不一定是这次一系列所有操作的数据.那只是操作过后所要保留下来的数据而以.为了触屏这样子的问题很多人一般都会写多几个按钮(如下图).把相应的操作都进行记录下来.这本来也不是什么不好的解决方法.但要是DataGrid这控件本来就是使用方便.管理数据还要这么多要求.那就有点偏离了这个控件的使用要求了.
这样的事情只有一两个业务单据就没什么.如果出现很多那就死得人多了.加上如果MVVM是操作的话大大加深了UI与后台的藕合度这可不利于维护的.出于项目功能还是自己写一个对应的集合吧.那自己写集合当然是要了我解集合所用到的接口DataGrid对操作要用到那些接口.写集合一般用到的接口或者说我们平时用到的List<T>这个数据集合是对实现了主要两个接口的分支IList<T>, IList这两个接口前者要做的是对泛型的管理(只管增删),后者是对Ojbect的管理(管增删之余还有属性说明这个合集是否固定长度[IsFixedSize],是否只读[IsReadOnly]). 那自定义的集合类最基本要实现的接口IList<T>, IList这两个接口下的所有方法.[IsFixedSize]属性让DataGrid集合容器知道当前数据集合是否可以添加\删除.那我们就继承这两个接口定义我们新的接口. 使用我们在新增时可付默认值,删除时可以验证数据是否删除.这两功能采用委托方法.为什么是委托而不是事件.个人觉得只有一个地方执行就够.没必要在这付点默认值在那个地方付点默认值.删除也是一样在一个地方控制就行了.
public class ActionList<T> : IActionList<T>,IActionList, INotifyCollectionChanged
{
/// <summary>
///
/// </summary>
public ActionList();
/// <summary>
///
/// </summary>
/// <param name="collection">编辑集合</param>
public ActionList(IEnumerable<T> collection);
}
构造函数说明.一个为空的构造函(这个原空集合最后所才生的都是要添增的数据),有参数的构造函数(集合最后保留的数据参数的默认为修改的集合中,如果有删除操作记录则移到移除集合中.如有添就新的则为新增的记录)
再者是分析DataGrid是什么动态添加删除的.装上ReSharper7插件在跳转到类的明细时可以选择从ReSharper那下载微软框架的源代码方便我们分析.当前分析环境为WPF.DataGrid控件是继承ItemsControl控件那数据源的最基本接口为IEnumerable那这个接口主要功能是让实现的类可以遍历.在看看DataGrid控件是怎么触发点击最后的空白行实现的添加行功能的.打开ReSharper下载的的源码.在[File Structure]窗口上过滤条件中输入为[Add]显示是用于Add相关的方法.
从过滤出来的记录来年AddNewItem就是我们要找到切入口了.双击打开对应的代码.
从源代码上看.UpdateNewItemPlaceholder方法是隐藏最后一空白行的.Items是实际显示的记录的集合容器.如果集合能更新则触发Adding事件,让用户可以对新的Item进行付初始值.大家应该还记录我们是给DataGrid付数据集合时是对ItemSource这个属性.但这好像没有ItemSource这个吧只有Item这就不对了.不过WPF有个特点就是依赖属性.让我们直接支看看ItsmSource这个依赖属性吧.
原来我们在为ItemSource付值时已经对Items付值了.ItemCollection控件都基本围绕着CollectionView\InnerItemCollectionView集合已在依赖属性中已经通过SetItemSource方法下的SetCollectionView把集合转换成CollectionView要用到的数据.一一打开对应的方法和函数最后的操作相关数据就是用到IList接口.
看来我平时用到的集合最后还是依赖于IList而泛型只是为了数据的直观\操作的方便进行二次封装而以.什么Array\ArrayList\List<T>\CollectionBase\Object[]都是实现IList接口