在DataGridView中,如何从自定义编辑控件中触发CellValueChanged事件?

4
我有一个DataGridView(WinForms),其中我定义了一个自定义的EditingControl,它派生自DataGridViewTextBoxEditingControl,只允许数字字符。
每当用户按下键时,我需要在DataGridView上引发CellValueChanged事件,但默认行为是仅在编辑完成后引发事件。
如何在每次按键时引发事件?
public class DataGridViewNumericTextBoxEditingControl : DataGridViewTextBoxEditingControl
{
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        e.Handled = Char.IsLetter(e.KeyChar);
        if (!e.Handled)
            RaiseDataGridViewCellValueChanged(); // <-- Any way?
    }
}

更新:

我已找到一种解决方法,但不确定它是否是一个好的解决方案:

public class DataGridViewNumericTextBoxEditingControl : DataGridViewTextBoxEditingControl
{
    protected override void OnKeyPress(KeyPressEventArgs e)
    {
        e.Handled = Char.IsLetter(e.KeyChar);
        if (!e.Handled)
        {
            EditingControlDataGridView.EndEdit();
            EditingControlDataGridView.BeginEdit(false);
        }
    }
}
1个回答

1
这里的目标是什么?看起来你正在尝试创建一个键盘掩码,其中任何不符合条件的字符都会引发警报?如果是这样,您可以通过添加MaskedTextBoxColumn在DataGridView中找到更好的解决方案。 MaskedTextBoxColumn以比强制编辑提交更合理的方式控制输入。
请参阅此处的代码,了解如何使用它:http://msdn.microsoft.com/en-us/library/ms180996.aspx 根据您在评论中更新的标准,听起来您的解决方案可能已经达到了最佳状态。但请注意,当其他控件基于键盘事件更新时,很容易陷入无限事件循环。最好在表单上有一个单一的委托处理所有事件,因为它可以通过状态丢弃虚假事件来防止事件触发的无限循环。
实际上,这将使用模型视图Presenter模式,其中您的委托充当Presenter并管理您的View(您的UI)上的流量。
通过这种方式,您甚至可以将Presenter逻辑移动到一个新类中,然后将其数据绑定,从而使您完全控制UI,而不是一堆事件处理程序。

我正在尝试检测单元格文本何时发生更改,而无需等待焦点离开单元格。 - Juanma
我想我应该重新表述一下:如果您正在尝试检测单元格更改,响应OnKeyPress等事件是可以的。我的观点是...也许您应该使用一个专门设计用于内在地掩盖输入为仅数字的控件。 - Godeke
我同意这一点,但真正的问题是当用户按下键时(即重新计算标签中显示的某些总数),我需要尽快更新屏幕上的其他控件。 - Juanma
好的: “只允许数字字符”的部分是一个误导。除非您有一些非常不寻常的设计要求,否则在数据网格中进行实时更新听起来像是一个非常糟糕的想法:撤消编辑的能力将会丢失。 - Godeke
再仔细思考一下,我认为你可能想要研究一下模型视图控制器(MVP)模式。更多信息请参见编辑后的答案。 - Godeke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接