提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2010-12-27 14:04:32.000|阅读 2358 次
概述:DataGrid 控件提供了一种灵活的方式来以行和列的形式显示数据集合。但却没有提供增加、删除行、即时输入等功能,若要实现类似于Winform下的DataGrid批量录入功能,还得做一些手脚,本文针对这几个问题,提出一些解决思路。
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
DataGrid 控件提供了一种灵活的方式来以行和列的形式显示数据集合。但却没有提供增加、删除行、即时输入等功能,若要实现类似于Winform下的DataGrid批量录入功能,还得做一些手脚:
1. 显示行号;
2. 即时输入;
3. 增加新行;
4. 删除行;
5. 复制、粘贴行/多行
本文针对这几个问题,提出一些解决思路。
1. 显示行号
网上也有一些显示行号的文章,但都是一个处理思路,就是在LoadingRow事件中做手脚,如这篇文章中所提供的思路《[Silverlight]奇技银巧系列-4 在DataGrid中显示行号》:
1: dataGrid1.LoadingRow += new EventHandler<DataGridRowEventArgs>(dataGrid1_LoadingRow);
2:
3: void dataGrid1_LoadingRow(object sender, DataGridRowEventArgs e) {
4: int index = e.Row.GetIndex();
5: var cell = dataGrid1.Columns[0].GetCellContent(e.Row) as TextBlock;
6: cell.Text = (index + 1).ToString();
7: }
SL帮助文档中对LoadingRow的解释是:"若要改进性能,DataGrid 控件不针对绑定数据源中的每个数据项实例化 DataGridRow 对象。而是仅当需要时才由数据网格创建 DataGridRow 对象,并尽量重复使用这些对象。例如,数据网格为当前位于视图中的每个数据项创建一个 DataGridRow 对象,并在行滚出视图之外时回收它。"
这个处理思路的一个问题,就是当DataGrid的行比较多,超出可视区域(出现滚动条)后;然后再删除前面的行,行号就废了。因为处于可视区域中的现有没有被删除的行,不会执行LoadingRow事件,所以显示的Index不会被更新。
处理思路:
我们一般是将ObservableCollection<Entity>作为DataGrid的数据源。一个变态的处理思路,就是给Entity增加一个Index属性(修改时引发PropertyChanged事件),然后再DataGrid的LoadingRow/UnloadingRow中,取得DataGrid的数据源ObservableCollection<Entity>,然后更新每个Index的值。
不过这样也有一个问题,就是在排序后,Index不会重新计算,显得有点乱。不知道排序会引发啥事件,如果在排序事件中也来更新一次Index,就没有问题了。哪位知道排序会引发啥事件,请告诉我,谢谢。/:)
2. 即时输入
默认情况下,DataGrid的Cell(TextBlock)不是出于编辑状态,要按F2或者鼠标单击,才能进入编辑状态(TextBox)。如果用鼠标点,或者每次都按F2,用起来非常不爽。
处理思路:
参考文章《An attempt to make the Silverlight DataGrid similar to Excel》,里面提出的思路就是在KeyDown\GotFocus\CellEditEnded三个事件中进行处理:
(1) KeyDown事件中,捕捉按键,如果是字符键,则记录到DataGrid.Tag中,然后执行dataGrid.BeginEdit(),强制DataGrid进入编辑状态。
(2) GotFocus事件中,将DataGrid.Tag中记录的字符取出来,然后付给输入框(TextBox);
(3) CellEditEnded事件中,清理DataGrid.Tag。
在该文的回复中,有人提出了一个可替代的事件组合:TextInput/PreparingCellForEdit/KeyDown。也是一个处理思路。
3. 增加新行
貌似新版本的SL,可以支持增加新行了。《微软发布Silverlight 4新版并更新Silverlight Tools和SDK》,但问题是,找遍了网络,竟然没有一个例子,M$的论坛上,也是只有提问没有答案。。。所以还是得自己动手。
处理思路:
快捷键:DataGrid的KeyDown事件中,判断按键;
增加新行:增加新行比较简单,上面提到,DataGrid的数据源是ObservableCollection<Entity>,因此,只要我们向该集合中增加一个元素,就能达到增加新行的目的。
4. 删除行
处理思路同增加新行:
快捷键:KeyDown中判断按键;
删除行:取得DataGrid的当前选择行dataGrid.SelectedItem as Entity,然后从将Entity从ObservableCollection<Entity>中删除。
5. 复制/粘行
处理思路1:
《An attempt to make the Silverlight DataGrid similar to Excel》一文中,也提供了一个复制/粘贴的思路:
主要分三个步骤:
(1). 获取DataGrid选择行,然后将每个cell(TextBlock)的中的文本数据,用"\t"分割,得到文本值;(如果Cell不在可视区域内,则调用dataGrid.ScrollIntoView,让Cell显示出来,然后才能取到TextBlock/TextBox)
(2). 将数据保存到系统的粘贴板:
1: var clipboardData = (ScriptObject)HtmlPage.Window.GetProperty("clipboardData");
2: clipboardData.Invoke("setData", "text", "格式化的自定义格式的数据");
(3). 从粘贴板上将数据取回来,再赋值给目标行中的Cell(TextBox):
1: var clipboardData = (ScriptObject)HtmlPage.Window.GetProperty("clipboardData");
2: string textData = clipboardData.Invoke("getData", "text").ToString();
但该文章中,只提供了单行复制/粘贴的功能;而且这段代码有很大局限性,只能在IE中运行。
处理思路2:
上面的复制/粘贴功能,只局限在IE中运行。另一个处理思路,可以做两点改进:
(1) 上面提到,DataGrid的数据源是ObservableCollection<T>,只要改变该集合中的值,SL就会自动刷新DataGrid。因此我们可以不用去操作DataGrid中的Cell,而是直接操作ObservableCollection<T>。拷贝的时候,对选中的一个或多个元素(Entity)执行xml序列化得到文本值;粘贴的时候,将文本值反序列化回来,然后对掉选中的元素(Entity)逐个属性赋值。
从ObservableCollection<T>得到文本值由两个处理思路:可以按上面描述的序列化来处理;也可以按处理思路1种的文本拼接思路,按照csv格式来进行拼接:属性值之间以"\t"分隔,元素(Entity)之间以"\r\n"分隔。
按csv格式拼接的好处,就是拷贝的数据,可以直接粘贴到Excel中。而序列化的好处,就是可以保证兼容性;譬如批量录入过程耗时可能比较长,中途可能需要跳转到其他页面、或者离开很久、或者下班关机,那前面录入的相当于白干了;因此需要在客户端提供了一个临时保存的功能:把当前数据保存到文件(SL4支持将数据保存独立存储区中),下次再从文件中把数据加载出来;但如果中途系统升级了,增加或者减少了一个字段/列,则序列化可以忽略增加/减少的列,继续正常工作。但CSV格式拼接出来的文本,缺少列描述信息,就挂了。
(2) 用一个TextBox做中转。将文本值赋值给中转的TextBox,然后对TextBox按Ctrl+C,从而将数据拷贝到系统的粘贴板;粘贴的过程正好反过来,先将系统粘贴板的数据,粘贴到中转用的TextBox,然后再取得TextBox中的值。
整个处理过程如下图所示:
在复制/粘贴的过程中,可能还会遇到一种情况,即选择了DataGrid中的N行,然后复制;但粘贴的时候,可能会选择M行,有三种情况需要考虑:
(1) M=N:这种情况下,正好元素可以一一匹配上;逐个元素按属性赋值就行;
(2) M>N:虽然粘贴时,选择的行数更多,但我们可以忽略多出的行(M-N),只处理前面的N行;
(3) M<N:此时,需要考虑多出的复制行(N-M)要怎么处理了;有三种处理办法:(1) 忽略多出的复制行;(2) 按照Excel的处理思路,只允许粘贴到连续的N行中;(3) 我的处理思路是,可以跨行粘贴,对于多出的行,可以插入到ObservableCollection<T>中。
6. 类图结构
7. 使用方法
1: dataGrid.UseExtender<Employee>();
这是最简单的情况,只提供基本的即时输入、增加、删除、复制、粘贴功能等;一个稍微复杂点的调用方式如下:
1: //happyhippy.cnblogs.com
2: //方法定义原型
3: public static void UseExtender<T>(this DataGrid dataGrid, string autoIncreaseField = "",
4: bool useXmlCopy = true, Action<DataGrid, EntityChangedEventArgs> rowsChanged = null,
5: bool addable = true, bool deleteable = true)
6: where T : class, new()
7:
8: //调用:
9: dataGrid.UseExtender<Employee>("Index", true,
10: (s, eventArg) =>
11: {
12: //取得刚操作(插入/删除)的元素集合,可以干一些后续的事情。。。
13: IList<Employee> changedEntities = eventArg.ChangedEntities as IList<Employee>;
14: }, true, true);
运行效果:
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:慧都控件网面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢