WPF DEV CellTemplateSelector(一个正确使用DevExpress CellTemplateSelector的Demo)
说明
我在项目中根据需求需要用到WPF Dev CellTemplateSelector时,遇到不少坑。曾一度想要放弃使用模板转换器,但又心有不甘,终于在不断努力下,达到了需求的要求。所以写下来和大家分享。如果有同样困惑的人,可以少走些弯路。笔者第一次写博客,文笔不好,还请见谅。
需求

需求很简单,选择方式下拉框选中时间控制方式或者价格控制方式,后面的控制点单元格对应显示日期控件或文本控件。
思路
刚拿到这个需求,就想到了模板选择器。但是之前也没有用过模板转换器,所以走了很多弯路。我们先看dev官方文档的说明
When using CellTemplate (or DataViewBase.CellTemplate) note the following: To enable data editing, use an editor shipped with the DevExpress Data Editors Library for WPF. The editor's Name must be set to 'PART_Editor'. When the editor's Name is set to PART_Editor, the grid automatically adjusts its appearance and synchronizes the editor with a source field specified by the FieldName or Binding properties. Standard controls can be used in CellTemplate only for display purposes. Data editing is not allowed. Templates specified via the DisplayTemplate and/or EditTemplate are ignored. A column's in-place editor specified via EditSettings, is also ignored.
意思就是说模板控件必须命名为“PART_Editor”,并且模板不需要绑定数据源,对应的GridControl的列绑定数据源即可,GridControl会自动将模板嵌入展示。我刚开始就是没有命名规范,并且在模板控件中绑定了数据源所以显示一直有问题。根据需求写出模板如下。
<Window.Resources>
<DataTemplate x:Key="FirstTemplate">
<StackPanel>
<dxe:DateEdit x:Name="PART_Editor" Mask="yyyy-MM-dd" MaskUseAsDisplayFormat="True">
</dxe:DateEdit>
</StackPanel>
</DataTemplate> <DataTemplate x:Key="SecondTemplate">
<StackPanel>
<dxe:TextEdit x:Name="PART_Editor"
MaskType="Numeric" Mask="n" MaskUseAsDisplayFormat="True" AllowNullInput="False" >
</dxe:TextEdit>
</StackPanel>
</DataTemplate>
</Window.Resources>
同时CellTemplateSelector需要继承DataTemplateSelector类,并且实现SelectTemplate方法根据条件返回一个你所需的Template.代码如下
public class SettingDataTemplateSelector: DataTemplateSelector
{
public DataTemplate FirstTemplate
{
get;
set;
}
public DataTemplate SecondTemplate
{
get;
set;
} public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
FrameworkElement element = container as FrameworkElement; EditGridCellData data = (EditGridCellData)item;
Setting setting = data.RowData.Row as Setting;
if (setting != null)
{ if (setting.ControlMode == )
return element.FindResource("FirstTemplate") as DataTemplate;
else
return element.FindResource("SecondTemplate") as DataTemplate;
}
return base.SelectTemplate(item, container);
}
}
然后前台xmal的CellTemplateSelector中引用选择器,代码如下
<dxg:GridColumn x:Name="ControlPointDataTime" Binding="{Binding Path=ControlPoint,Mode=TwoWay}" Header="控制点" >
<dxg:GridColumn.CellTemplateSelector>
<local:SettingDataTemplateSelector
FirstTemplate="{StaticResource FirstTemplate}"
SecondTemplate="{StaticResource SecondTemplate}" />
</dxg:GridColumn.CellTemplateSelector>
</dxg:GridColumn>
基本的需求就完成了,是不是看着很简单。其实当你觉得简单是因为你了解了DEV的一些机制,比如模板控件的命名必须是“PART_Editor”,还有绑定的地方,任何一个地方出错了前台运行显示都是不会称心如意的,这个时候你就会找不到解决的办法,从而达不到你想要的目的。上面的需求其实还有一个问题,比如:当你添加一条记录是金额控制的,此时这条记录已经添加到数据中了。如果你在界面上修改将下拉框选中改为时间控制,后面一列由于因为无法转换为时间格式,所以显示仍然有问题。此时怎么办呢,我想到了GridControl的CellValueChanged事件,当我切换控制方式时,后面一列我给它清空,这样直接让用户输入不就好了。在这里我也将代码贴出来。
private void ViewSimulate_CellValueChanged(object sender, CellValueChangedEventArgs e)
{
if (e.Column == ComControlMode)
{
((GridControl) e.Source.DataControl).SetCellValue(e.RowHandle,ControlPointDataTime,null);
}
}
到此,项目运行起来看着还行,虽然需求很简单,但也折腾了我一段时间,今后我会不断的写博客来记录我遇到的坑来和大家分享,同时也方便我自己查看。最后,我将完整的demo上传供大家参考,我用的dev的版本是15.2.4,如果你的版本和我的不一样,可以将demo中的引用删除换成自己的就可以了。
补充:当系统时间设置如下时,前台界面将显示混乱。

前台显示如下

当我发现这个问题,我一时没有更好的解决办法。前台模板DateEdit的Mask、DisplayFormatString以及MaskUseAsDisplayFormat都设为True。于是我向DevSupport寻求帮助。DevSupport给出解释如下:
The cause of the issue is that date values are stored as string values. In this scenario, DXGrid posts the values in the current culture to maintain end-user input.
DateEdit editors, however, use an invariant culture to parse string values.
To resolve this issue, you can either store the date values as DateTime or additionally convert posted values. With your current implementation,
the second approach can be implemented by setting Binding.Converter to a custom converter
在此,我给出第二种方法的实现方式。
public class ConvertDateTime : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
} public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
DateTime date;
if (value is string && DateTime.TryParse((string)value, out date))
return date.ToString(CultureInfo.InvariantCulture);
return value;
} public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
前台添加Convert转化绑定
<dxg:GridColumn x:Name="ControlPointDataTime" Binding="{Binding Path=ControlPoint,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,NotifyOnSourceUpdated=True,Converter={local:ConvertDateTime}}" Header="控制点" >
到此,问题就解决了。
补充2:对于上面的切换控制方式时,后面一列清空的需求这里有更简单的实现方式,只需要将你自定义的类中的属性加上一些逻辑控制就好了,代码如下:
private int _ControlMode;
public int ControlMode
{
get { return _ControlMode; }
set { _ControlMode = value;
ControlPoint = null;
}
}
将修改后的源码重新上传。
源码下载:http://files.cnblogs.com/files/damon-xu/demo.rar
WPF DEV CellTemplateSelector(一个正确使用DevExpress CellTemplateSelector的Demo)的更多相关文章
- WPF依赖属性的正确学习方法
前言 我在学习WPF的早期,对依赖属性理解一直都非常的不到位,其恶果就是,我每次在写依赖属性的时候,需要翻过去的代码来复制黏贴. 相信很多朋友有着和我相同的经历,所以这篇文章希望能帮助到那些刚刚开始学 ...
- wpf只运行一个实例
原文:wpf只运行一个实例 在winform下,只运行一个实例只需这样就可以: 1. 首先要添加如下的namespace: using System.Threading; 2. 修改系统Main函数, ...
- WPF DataGrid绑定一个组合列
WPF DataGrid绑定一个组合列 前台: <Page.Resources> <local:InfoConverter x:Key="converter& ...
- js替换全部,js检查输入的日期是否是一个正确的日期格式
<script language="javascript"> var str = "我爱的人和爱我的人,我爱的人和爱我的人"; var newstr ...
- 在 WPF 中获取一个依赖对象的所有依赖项属性
原文:在 WPF 中获取一个依赖对象的所有依赖项属性 本文介绍如何在 WPF 中获取一个依赖对象的所有依赖项属性. 本文内容 通过 WPF 标记获取 通过设计器专用方法获取 通过 WPF 标记获取 p ...
- 你的团队需要一个正确的程序集(dll)管理姿势
很多团队经历时间的积淀之后,都会有很多的可重用的公共技术组件.大部分的团队都会把这些公共组件生成程序集(dll)后,放到GIT或SVN的一个公共目录里面,以供各个项目中使用.起初在项目很少又或者是公共 ...
- devexpress 如何读demo源码 总结
对于初学这个庞大的控件集合的程序猿来讲应该是有些难度的.今天就devexpress demo 里边一些东西就本人的所学做一下引导吧. dev 有个帮助文件 DevExpress 中文帮助文档 和每个 ...
- 一个简单的MariaDB认证插件demo
代码地址如下:http://www.demodashi.com/demo/13076.html 一.前言 众所周知(其实可能很多人不知道)MariaDB支持插件认证.在MariaDB中新建用户,常见的 ...
- 一个基于ES5的vue小demo
由于现在很多vue项目都是基于ES6开发的,而我学vue的时候大多是看vue官网的API,是基于ES5的,所以对于刚接触项目的我来说要转变为项目的模块化写法确实有些挑战.因此,我打算先做一个基于ES5 ...
随机推荐
- 用Quick Cocos2dx做一个连连看(三)
做个日记吧. 最近比较忙,斗志也不高,昨天有点时间了,开始做了一下连接方法,一开始用的搜索算法,但是bug比较多,究其原因是对语法和算法都不是很熟悉. 然后昨天下午利用点时间用稍微通俗一点的连接算法, ...
- PHP 实现冒泡法排序
<?php $nums = array(10,0,20,30,50,40,80); function stor($numbers){ $length = count($numbers); for ...
- 19、手把手教你Extjs5(十九)模块Grid的其他功能的设想
经过对自定义模块和Grid的设计和编码,现在已经能对一个有配置信息的模块来生成界面并进行一些简单的CURD操作.由于这是一个全解释性的前台的架构,因此你想到的任何新主意都可以放到所有的模块中. 比如对 ...
- PHP访问接口获取数据
如:http://localhost/operate.php?act=get_user_list&type=json 在这里operate.php相当于一个接口,其中get_user_list ...
- KERMIT,XMODEM,YMODEM,ZMODEM传输协议小结(转)
源:KERMIT,XMODEM,YMODEM,ZMODEM传输协议小结 Kermit协议 报文格式: 1.MARK,起始标记START_CHAR,为 0x01(CTRIL-A): 2.LEN,报文剩余 ...
- IOS NSURLRequest 设置 Header
https://my.oschina.net/wolx/blog/406092 工程中的请求,需要设置Header,请求令牌才访问,NSURLRequest 请求没有直接设置header 的方法,需要 ...
- ERP软件数据库覆盖数据恢复成功/重装数据库系统软件,导致同名文件覆盖
ERP软件数据库覆盖数据恢复成功/重装数据库系统软件,导致同名文件覆盖 [数据恢复故障描述] 上海某酒店ERP软件原来安装在C盘上,用户误操作把软件进行了卸载,发现软件没有了, 但操作之前没有把原 ...
- jquey插件开发
1.概述 jquery插件开发的主要方法有三种: 1.通过$.extend()来扩展jQuery,即在jQuery命名空间下扩展属性,直接在$对象下调用,不需要再dom下调用,也无法在dom元素下调用 ...
- JVM面试
深入理解Java内存模型:http://www.cnblogs.com/skywang12345/p/3447546.html http://www.infoq.com/cn/articles/jav ...
- [转python 父类可以调用子类的方法
问题描述:我也是在读500 Line 里满的DBDB 的代码时发现的,python的父类可以调用子类的方法,这跟平常习惯的理解方式很不一样,所以就查了下原因,记录如下: 1.现象:最近使用到了So ...