现象
最近使用WPF来制作波形绘制软件,其中波形的数据是我自己定义的一个类,这个类绑定到了界面上的DataGuid,这样就可以通过界面上改变类的属性来改变界面上的波形形状。整体的结果类似下面这张图。
但是在实际操作中出现了一个问题:用户如果想要改变波形的形状,就必须先选择一个脉冲所在的条目,接着才能改变其数据(或者连续修改同一条目中的数据,但是第一次修改数据会无效,第二次及以后的数据修改会恢复正常)。但实际需要实现的是,用户即使不选定脉冲的条目,当脉冲数据改变时,整个波形也能随之改变。
原因
自定义的两个类:
Pulse类 —>绑定界面中DataGuid,用来显示波形中的每个脉冲的数;
LinePoint 类 —>接受Pulse类中的数据,生成绘制脉冲所需要的拐点数据。
整个过程的数据传递:
DataGuid中控件的数据改变–>对应Pulse类中数据改变–>LinePoint类数据改变–>界面波形改变
所以,导致发生此现象的原因是:当首次点击DataGuid中的一个Item中的一个控件时,DataGuid此时并不能选定点击的Item,从而导致首次的数据修改会失效,而第一次的修改数据过后,DataGuid才会选定被点击的Item。
修改
修改的主要目的是,DataGuid能在控件首次修改数据时就能选定控件所在的item。
旧代码:
此函数为前臂时间改变的控件的处理函数
// 前臂时间改变
private void UIFtime_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e) {
int item = UIWaveTable.SelectedIndex; //获取选定的item,UIWaveTable为绑定的DataGuid的名字
Console.WriteLine(item);
}
这样更换item后的首次操作输出的值仍然为上次获取到的item值。
解决办法:
// 前臂时间改变
private void UIFtime_ValueChanged(object sender, RoutedPropertyChangedEventArgs<object> e) {
object clicked = (e.OriginalSource as FrameworkElement).DataContext;
var lbi = UIWaveTable.ItemContainerGenerator.ContainerFromItem(clicked) as DataGridRow;
lbi.IsSelected = true;
int item = UIWaveTable.SelectedIndex; //获取选定的item,UIWaveTable为绑定的DataGuid的名字
Console.WriteLine(item);
}
添加了三行代码,此三行代码的作用是,当用户修改控件内容时,代码自动追溯到当前控件所处的item并将其设置为选定状态。
结果
修改完成后程序不再出现上述现象,可以正常使用。