简单来说,FocusedRowObjectChanged事件,在正常的表格动作下,不会被触发,当鼠标点击任意控件单元格或位置时会被触发。即使画面有数据的加载或更新,都不代表会触发此事件。
所以除非业务需求会有鼠标或点击性事件的参与,否则利用此事件去响应,并不保险。
我的业务如下:画面显示50到70行不等。加载后,根据我的业务需要,会逐行向下执行。在画面上,要求,已执行的行为绿色,当前正在执行行为黄色,未执行为灰色或默认无颜色。根据触发条件,画面上的行会依次变色。
一开始,我是用焦点行来显示黄色的正在执行行的。通过改变Dev控件的FocusedRowHandle 的值来变换焦点行,而焦点行赋值背景色为黄色。但是这样经常出问题,由于我的设备是触摸屏。当点击到画面任意一行时,焦点行就会被改变。如果加载了FocusedRowObjectChanged事件,则即使在人工或手动点击的情况下,焦点行同样会被改变。
而后,我尝试采用数据源的方式处理。即,未完成或已完成时,我的数据源中的某字段会记录此标记状态。利用这个。当我每次画面完成时,更新数据源中对应行的标记状态,而后刷新数据源,以达到效果。
在这里,用到了一个gvRecord_RowStyle 事件。顾名思义,是行样式事件。控件每加载一行数据时都会进入到此事件。
int hand = e.RowHandle;
获取到行句柄,如果有行,则为行号,如果没有,则默认为-1。所以,至少,当此值小于0时,是不需要处理的,return出去。
然后,行句柄与我的数据源集合的顺序是一致的。所以,可以认为行句柄就是我数据源集合中的第某个元素。
if (_formualDTOs[hand].Complete == true)
{
//var a = sender;
e.Appearance.BackColor = Color.Green;
}
else if (_formualDTOs[hand].Complete.Equals(false) && hand.Equals(0))
{
e.Appearance.BackColor = Color.Yellow;
}
我的数据源中有Complete字段来标记是否已完成。所以利用此字段进行判断赋值。绿色或黄色。
完整的判断,就不写了,第一行或者最后一行时的情况也要考虑进去。否则空指针会报错。
这里讲到了gvRecord_RowStyle事件,那么,这个事件是怎么触发的呢?,这个事件是在填充数据之后渲染画面时触发的。填充数据,
我用的是gvRecord.RefreshData(); 刷新数据源。
不需要重新赋对应的Datasource给到控件,在这50--70行的执行过程中,状态变化,使用gvRecord.RefreshData();即可。同源更新数据,而不是重复的清空数据源,赋予数据源刷新。没必要。同时,BestFit也不建议使用。会消耗很多性能。
同样,我也建议加上
//gvRecord.BeginUpdate();
gvRecord.RefreshData();
//gvRecord.EndUpdate();
按官方释义,gvRecord.BeginUpdate(); 时,控件会被独占,直到 //gvRecord.EndUpdate();时解锁。类似于Lock或者是using效果。对于一些性能较弱的机器,可能第一行数据刷新完以后,控件正在渲染画面,而此时又执行了第二条数据的刷新,就有可能会导致报错。利用刷新锁,可以避免部分这样的情况。
当然,大家的场景都不一样。如果按上述方法处理后,程序依旧报错,且报错位置在Drawing或者Print一类的方法时。
需要在刷新画面或数据源时回到主线程执行。