DataGridView.RowLeave在Form按钮之前触发.MouseClick

问题描述 投票:0回答:3

我在任何地方都找不到任何相关内容:我有一个带有DataGridView和一些按钮的表单。当选择了一行datagridview,然后单击一个按钮(在表单上)时,dgv.RowLeave会在其他任何内容之前触发。它甚至在Click或MouseClick之前触发。

这是有道理的,但问题是RowLeave(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs)的发件人是DataGridView,而不是按钮。因此,在这一点上似乎不可能知道点击了什么按钮,因为sender和e都引用了DataGridView,而不是Form和Buttons。

触发Click事件,但仅在处理RowLeave之后触发。

那么有什么方法可以知道用户点击的位置,在RowLeave做其他事情之前(在我的情况下,导致Button.Click永远不会被处理),或者然后从RowLeave中?

Class MainForm
' The form contains a DataGridView and btnQuit (and other buttons)

Private Sub dgv_RowLeave(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dgv.RowLeave

  ProgrammaticallyDoRowValidation(dgv.CurrentRow.Index) ' This does validation and more. 
  ' But if btnQuit is clicked, I need to know here, or before RowLeave is
  ' triggered and NOT do this row validation.
  ' ...
End Sub

Private Sub Form_Click(sender As Object, e As EventArgs) Handles MyBase.Click
  Dim frm As Form
  frm = CType(sender, Form)
  ' Translated from Sach's comment below. Code never reaches this event
  '(RowLeave prevents it).
End Sub

Private Sub Quit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnQuit.MouseClick

  QuitPgm() ' Contains some more stuff.
  ' Also never executed, because RowLeave is handled first.

End Sub
End Class
vb.net forms datagridview mouseclick-event
3个回答
0
投票

我在这里使用WinForms,但想法是一样的。

因此,Events与Controls相关联。 ButtonControlDataGridView也是如此。然后在Code Behind中你有Event Handlers,它们本质上是与Control Events相关的方法。

因此当你将一个Click事件附加到一个按钮,幕后,VB.NET创建一个像这样的Event Handler

private void button1_Click(object sender, EventArgs e)
{

}

现在sender是一个对象,但它实际上是通过那里的DataGrid。所以与你的陈述相反所以现在似乎不可能知道点击了什么按钮你知道是否点击了一个按钮。如果是,并且如果你附加了一个事件处理程序,它将被调用。例如,这将显示带有按钮文本的MessageBox

private void button1_Click(object sender, EventArgs e)
{
    var btn = (Button)sender;
    MessageBox.Show(btn.Text);
}

因此,如果您想知道是否单击了Form,请附加Click事件处理程序:

private void Form1_Click(object sender, EventArgs e)
{
    var frm = (Form)sender;
    MessageBox.Show(frm.Text);
}

0
投票

我不确定你是如何阻止RowLeave事件中的按钮单击,但我认为你应该使用RowValidating事件来验证DataGridView。假设我们有一个只有1列和一个Button的DataGridView。验证是列值不得高于100.如果我们将验证放在RowValidating事件中,则在Leave事件之后但在Validated事件之前触发验证。如果验证失败,则不会触发子序列事件。

Public Class Form1

    Function ProgrammaticallyDoRowValidation(i As Integer) As Boolean
        If Convert.ToInt32(dgv(0, i).Value) > 100 Then
            Return False
        Else
            Return True
        End If
    End Function

    Private Sub dgv_RowValidating(sender As Object, e As DataGridViewCellCancelEventArgs) Handles dgv.RowValidating
        If Not ProgrammaticallyDoRowValidation(dgv.CurrentRow.Index) Then
            e.Cancel = True
        End If
    End Sub

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show("Buton clicked")
    End Sub

End Class

尝试运行代码并在列中输入大于100的值。您无法单击该按钮,因为它未通过验证。但是如果你将ButtonCausesValidation属性设置为False,则不会触发验证。

根据this link的事件顺序是这样的:

通过使用键盘(TAB,SHIFT + TAB等)更改焦点,通过调用Select或SelectNextControl方法,或通过将ContainerControl.ActiveControl属性设置为当前窗体,焦点事件按以下顺序发生:输入 - > GotFocus - >离开 - >验证 - >验证 - > LostFocus

当您使用鼠标或通过调用Focus方法更改焦点时,焦点事件按以下顺序发生:输入 - > GotFocus - > LostFocus - >离开 - >验证 - >验证


0
投票

那么有什么方法可以知道用户点击的位置,在RowLeave做其他事情之前(在我的情况下,导致Button.Click永远不会被处理),或者然后从RowLeave中?

Private Sub dgv_RowLeave(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dgv.RowLeave

  ProgrammaticallyDoRowValidation(dgv.CurrentRow.Index) ' This does validation and more. 
  ' But if btnQuit is clicked, I need to know here, or before RowLeave is
  ' triggered and NOT do this row validation.
  ' ...
End Sub

这是一个kludge解决方案,但在DataGridView.RowLeave事件中,你可以检查ContainerControl.ActiveControl Property是否是你想要测试的当前活动控件。在这种情况下,ContainerControlForm

Private Sub dgv_RowLeave(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles dgv.RowLeave

    ProgrammaticallyDoRowValidation(dgv.CurrentRow.Index) ' This does validation and more. 
    ' But if btnQuit is clicked, I need to know here, or before RowLeave is
    ' triggered and NOT do this row validation.
    ' ...
    If Me.ActiveControl Is btnQuit Then
        ' do something
    End If
End Sub
© www.soinside.com 2019 - 2024. All rights reserved.