我正在使用DataGridView,并使用CellValueChanged
事件。
当我通过代码更改单元格值时,我不希望触发此事件。但是,我希望在用户编辑它时触发它。
这就是我使用以下代码附上我的单元格值更改操作的原因:
void changeCellOperation()
{
dgv.CellValueChanged -= new DataGridViewCellEventHandler(dgv_CellValueChanged);
...
cell.Value = myNewCellValue
...
dgv.CellValueChanged += new DataGridViewCellEventHandler(dgv_CellValueChanged);
}
我结束了几个不同的函数,我的DataGridView单元格以这种方式更新。
因为这些函数是从不同的地方调用的并且可以嵌套,所以我不能保留这些代码,以避免事件不需要的事件重新激活。
所以我这样结束了:
int valueChangedEventMask = 0;
void changeCellOperation()
{
valueChangedEventMask++;
...
cell.Value = myNewCellValue
...
valueChangedEventMask--;
}
void dgv_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (valueChangedEventMask > 0)
return
...
}
这很好用。此外,当嵌套调用时,包括事件本身内部。
但CellValueChanged
事件现在无理由地激发了太多次。
因为我经常需要处理这种模式,所以我正在寻找一种适用于UI中事件的解决方案,而不仅仅是DataGridView。
所以我的问题是:
正确掩盖UI事件并避免不必要的事件触发的最佳提示是什么?
答案 0 :(得分:0)
CellValueChanged
不是UI事件,而是属性更改事件。这意味着您无法使用它来区分用户输入和程序化更改。你总是可以使用subscriber / unsucscribe或flag +/-或BeginEdit / EndEdit类似的技术,但也许你必须找到另一种(更好的)方法。例如,如果是复选框,您可以使用Click
事件而不是Changed
,因为(惊喜!)它会告诉您用户何时单击它,否则以编程方式安全地更改Checked
的值
如果DataGridView
最简单,可以使用带有标记的Changed
(在编辑开始时设置,在结束时重置 - 请参阅CellBeginEdit/CellEndEdit
)。
答案 1 :(得分:0)
您可以使用CellEndEdit
代替CellValueChange
。我不知道你的方法dgv_CellValueChanged
做了什么,只要注意每次退出单元格的编辑模式时都会触发CellEndEdit
,即使它的值没有被更改。这意味着如果您不希望在值没有更改时执行该方法,则必须跟踪单元格的当前值。
我会避免与鼠标相关的事件,例如CellClick,因为您的用户只能使用键盘。
无论如何,我通常通过将逻辑与用户界面分开来避免这种问题,即我写了一个绑定到表单的单独的类。看一下MVVM(你可以在WinForms中实现自己的版本,如果你想要的话)或好的MVC。
答案 2 :(得分:0)
我最终将这两种解决方案混合在一起非常简单。我使用了一个计数器,我只挂钩/取消挂钩我要屏蔽的事件。
EventMask valueChangedEventMask;
// In the class constructor
valueChangedEventMask = new EventMask(
() => { dgv.CellValueChanged += new DataGridViewCellEventHandler(dgv_CellValueChanged); },
() => { dgv.CellValueChanged -= new DataGridViewCellEventHandler(dgv_CellValueChanged); }
);
// The value change operation I want to hide from the event
void changeCellOperation()
{
valueChangedEventMask.Push();
...
cell.Value = myNewCellValue
...
valueChangedEventMask.Pop();
}
// The class
public class EventMask
{
Action hook;
Action unHook;
int count = 0;
public EventMask(Action hook, Action unHook)
{
this.hook = hook;
this.unHook = unHook;
}
public void Push()
{
count++;
if (count == 1)
unHook();
}
public void Pop()
{
count--;
if (count == 0)
hook();
}
}