【问题标题】:Validate DataGridView on menu item click在菜单项单击时验证 DataGridView
【发布时间】:2011-06-19 17:01:47
【问题描述】:

您好,我有一个包含菜单栏、工具条和 DataGridView 控件的 Windows 窗体。 我正在使用 VB.Net。

我在工具条上有一个保存按钮和一个保存菜单项。我需要在保存之前运行验证。我的问题是,如果更改单元格值,然后单击任一保存按钮,验证不会运行,因此不会保存新值。

我查看了 DataGridView 上的事件,例如“离开”事件,但似乎没有一个符合我的要求。 IE。单击任一保存按钮时,“离开”不会运行。

有没有人知道当点击其中一个按钮(或任何其他按钮)时我可以运行验证代码的方法。

非常感谢任何帮助!

【问题讨论】:

    标签: .net winforms datagridview validation


    【解决方案1】:

    我也遇到了同样的问题,各种论坛上的回复都没有解决我的问题。就我而言,表格上有多个网格。甚至其他用户控件中的一些网格。所以我创建了以下例程,并在相关的 ToolStrip 点击事件中调用了 CommitGridEdit()。它似乎对我有用。

    Public Sub CommitGridEdit(ByVal frm As Form)
        ' Clicking on a ToolStrip menu item will not cause the grid to end editting the current cell.
        ' So we have to find if any grid is in edit mode and do this ourself.
        Dim grid As DataGridView = GetFocusedGrid(frm)
    
        If grid Is Nothing Then Exit Sub
    
        If Not grid.CurrentCell Is Nothing Then
            If grid.CurrentCell.IsInEditMode Then
                grid.EndEdit()
            End If
        End If
    End Sub
    
    Private Function GetFocusedGrid(ByVal ctl As Control) As DataGridView
        For Each c As Control In ctl.Controls
            If TypeOf c Is DataGridView AndAlso c.ContainsFocus Then
                Return c
            ElseIf c.Controls.Count > 0 Then
                Dim c2 As Control = GetFocusedGrid(c)
                If Not c2 Is Nothing Then Return c2
            End If
        Next c
        Return Nothing
    End Function
    

    【讨论】:

      【解决方案2】:

      对我来说,从菜单的点击事件中调用表单的“验证”函数就足以满足我的需要,其中包括强制触发网格的验证事件。

      【讨论】:

      • Validate() 对我不起作用,但 ValidateChildren() 起作用。这可能不是最干净的解决方案,但我能够强制网格验证而不以编程方式尝试更改单元格的唯一方法,这将是一个更糟糕的解决方案。
      【解决方案3】:

      问题在于,单击ToolStrip 控件上的按钮或MenuStrip 控件上的项目不会导致Validating/Validate 事件由当前选中的控件。这是设计使然。与菜单和工具栏交互不会导致当前选定的控件失去焦点,这意味着永远不会触发验证。

      如果您仔细考虑一下,这甚至是有道理的。想象一下,您的验证逻辑要求每个单元格包含一个值(即,它防止单元格留空或为空)。如果每次用户尝试从菜单或工具栏中选择项目时都会触发验证事件,那么他们甚至无法将任何内容“粘贴”到单元格中!

      如果您坚持覆盖此行为,您将不得不在表单中添加一堆丑陋的附加逻辑,并且冒着严重惹恼用户的风险。说我不推荐就够了。

      更好的解决方案是将验证逻辑提取到单独的方法中,并在要触发验证的每个菜单/工具条项的事件处理程序方法的开头手动调用它。或者,您可以使用InvokeLostFocus method 在保存工具条按钮单击事件处理程序的开头为您的DataGridView 控件引发LostFocus 事件。比如:

      InvokeLostFocus(myDataGridView, EventArgs.Empty)
      

      【讨论】:

        【解决方案4】:

        虽然在Leave 事件触发后对TextBox 等控件进行验证,但DataGridView 控件仅在编辑模式下执行验证,并且仅在每个单元格的基础上执行。

        您可以在DataGridView 上处理CellValidating 事件以捕捉当前单元格进行验证的时刻 - 如果焦点从网格移动到您的保存按钮,则会触发此事件。如果单元格的值无效,您可以将DataGridViewCellValidatingEventArgs 对象上的Cancel 属性设置为true

        【讨论】:

        • 虽然这一切都是正确的,但仍然不能解决提问者的问题。单击ToolStrip 项目实际上不会触发验证事件,因为当前选定的单元格仍处于选中状态。详情见我的回答。
        • 啊,是的,我应该意识到这一点。我最近正在利用这种行为来实现自定义下拉控件:P
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-05-13
        • 1970-01-01
        • 2014-04-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多