这篇随笔总结dx wpf使用中的各种坑,持续更新~

  1. LookUpEdit里内嵌的DXGrid的名字必须是“PART_GridControl”,不能不写、也不能写错。我对比了2个小时,从ViewModel到MergedResources,真没往这个方向想。当然,后来查出LookUpEdit的Document里粗体标出了这句话:Note: the embedded DXGrid name must be set to PART_GridControl.汗!咋就忘了先查一下他们家的文档呢。下次用某个控件之前,一定要先大致把文档扫一下。唉,不过很多时候,先扫文档也有点浪费时间。但出了问题,确实应该第一时间扫一下。

  2. 关于泛型控件的继承问题,1)控件的基类不能带有xaml,如果想要带上控件,只能用代码生成咯;2)泛型控件的声明如下,注意要带上x:TypeArguments才行,否则泛型类声明不完整,编译出错;3)另外由于WindowBase并没有Resources,因此要在基类里找。

//cs部分
public partial class Window1 : WindowBase<Window1ViewModel>
//xaml部分
<my:WindowBase x:Class="Window1" x:TypeArguments="vm:Window1ViewModel"
               xmlns:my="clr-namespace:TestWpf.Base"
               xmlns:vm="clr-namespace:TestWpf.ViewModel">
  <Window.Resources>

3.关于SpinEdit,如果把值绑定到SpinEdit.EditValue,再添加Validate事件,很容易出现明明是正确的值,却显示验证错误:未能转换值 "0"的提示。绑定到SpinEdit.Value(这是decimal的)或者SpinEdit.Text(这是string的)都OK。猜测是Dx里自带了StringToDoubleConverter+DecimalToDoubleConverter之类的,却没有ObjectToDouble的Converter,唉,找了半天!例子在此

4.关于FilterString里的Between,第一次绑定时有效,以后就无法绑定过滤了。然后给DevExpress发了邮件例子在此 这里要赞一下DevExpress的SupportTeam,当天就给了回复,原因当然是自己2B了,因为FilterString默认是单向绑定的,这也算是WPF里面常见的问题了,可惜自己以前没踩进来,印象不深。
另外:Between的Format应该是:[FieldName] Between({0}, {1}),注意不要加单引号,不能写成这样:Between('{0}', '{1}')。我当时看到Dx显示出来是带单引号的,所以我按照单引号拼接FilterString,无效,汗!

5.接着4.说一下WPF里的BindingMode和UpdateSourceTrigger。这2个属性的Default值都是因控件而异的,这个设定有点贱!具体某个控件的默认值是OneWay|TwoWay、还是PropertyChanged|LostFocus,全由控件自己在.cctor()里定义。因为控件的DP实在太多了,没有完整的列表。当然也有一个通用的准则:能够与用户交互的属性一般是双向绑定;不能与用户交互的一般是单向绑定。前者,比如TextBox.TextProperty和CheckBox.IsCheckedProperty;后者,比如我踩的这个坑:GridControl.FilterStringProperty。有2种方式可以知道某个属性的默认值到底是什么:
1)用如下代码:

var meta = DataControlBase.FilterStringProperty.GetMetadata(typeof(GridControl)) as FrameworkPropertyMetadata;
if(null != meta) return;
Console.WriteLine(meta.BindsTwoWayByDefault);
Console.WriteLine(meta.DefaultUpdateSourceTrigger); 

这里有一个继承关系:FrameworkPropertyMetadata->UIPropertyMetadata->PropertyMetadata。大部分DP的元数据都只是PropertyMetadata,那自然也就没有BindsTwoWayByDefault属性,这种情况下,默认是OneWay(Why? 我没找到源码,呵呵)。UpdateSourceTrigger相对简单,默认都是PropertyChanged,目前只知道TextBox是默认LostFocus的,其他慢慢再积累吧。
2)直接用ILSpy或者Reflector去源码里找,又快又方便。在各个控件的.cctor()里找到如下的代码,一目了然:

TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(TextBox), 
    new FrameworkPropertyMetadata(string.Empty, 
	FrameworkPropertyMetadataOptions.Journal |
	FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, 
	new PropertyChangedCallback(TextBox.OnTextPropertyChanged), 
	new CoerceValueCallback(TextBox.CoerceText), 
	true, 
	UpdateSourceTrigger.LostFocus));

但也有个小问题,不管哪个工具,居然都解析不出PresentationFramework里的源码,这是啥原因?知道的同学请指教!
3)最后小结是:为保险起见,不妨总是显示设置Mode=TwoWay,一旦忘了,找起来要多花很多时间哦。

6.Dx的Grid里的VisibleIndex的行为有点怪,刚开始可能会有些疑惑。反复尝试,发现关键是在前后加上Begin/EndUpdate(),代码如下:

grid.Columns.BeginUpdate();
foreach(var item in grid.Columns) {
  if(list.Contains(item.FieldName)) item.Visible = true;
  else item.Visible = false;
}
for(int i=0;i<list.Count;i++){
  grid.Columns[list[i]].VisibleIndex = i;
}
grid.Columns.EndUpdate();

7.1)Dx的Chart里有数据聚合的概念,为的是把大量的数据聚合成离散的点,便于清晰显示,详细见[这里]。用ContinuousDateTimeScaleOptions会导致Bar类型不显示,改用Automatic或Manual可以。2)BarSeries2D.BarWidth表示基于刻度的比例,而不是像素。详情见[这里]。3)AxisLabel.TextPattern是Dx自定的StringFormat,除了C#里常规的F1、N3、P2之类的,还包括自定的关键字,比如{A}:Argument、{V}:Value等,详情见[这里]。4)设置EnableAnimation=True(注意这个属性在设计器里不可见)或AnimationMode=OnLoad,可以启用动画功能。但如果设置AnimationAutoStartMode=SetStartState的话,会导致Chart不显示,Dx的文档里提到了这点,但深层原因不明,详情见[这里]。另1个枚举值SetFinalState会导致动画无效。设置PlayOnce或者干脆不设置都OK。但奇怪的是,Dx提供的例子ChartsDemo->PanesControl里却可以,呵呵。5)Dx的WPF目前尚不支持ScaleBreaks,WinForm的版本是支持的,常见的例子是中午11:30-13:00休市期间的数据为空。这个比较无语,详情见[这里]。

 posted on 2015-08-20 21:23  AlexanderYao  阅读(1451)  评论(0编辑  收藏  举报