Vb.net DataGridView.RowLeave在窗体按钮之前激发。鼠标单击
我在任何地方都找不到关于这个的任何信息: 我有一个带有Vb.net DataGridView.RowLeave在窗体按钮之前激发。鼠标单击,vb.net,forms,datagridview,mouseclick-event,Vb.net,Forms,Datagridview,Mouseclick Event,我在任何地方都找不到关于这个的任何信息: 我有一个带有DataGridView和几个按钮的表单。选择datagridview的一行后,我单击表单上的一个按钮,dgv.RowLeave将在其他任何操作之前触发。它甚至在单击或鼠标单击之前触发 这是有道理的,但问题是RowLeave(ByVal sender作为对象,ByVal e作为DataGridViewCellEventArgs)的发送者是DataGridView,而不是按钮。因此,似乎不可能知道此时单击了什么按钮,因为sender和e都引用D
DataGridView
和几个按钮的表单。选择datagridview的一行后,我单击表单上的一个按钮,dgv.RowLeave
将在其他任何操作之前触发。它甚至在单击或鼠标单击之前触发
这是有道理的,但问题是RowLeave(ByVal sender作为对象,ByVal e作为DataGridViewCellEventArgs)
的发送者是DataGridView,而不是按钮。因此,似乎不可能知道此时单击了什么按钮,因为sender和e都引用DataGridView,而不是表单或按钮
单击事件将被触发,但仅在处理RowLeave后触发
那么,在RowLeave执行其他操作之前(在我的情况下,导致出现按钮。单击以永不处理),或者从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
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
我在这里使用的是
WinForms
,但想法是一样的
因此事件
s附加到控件
s。按钮
是一个控件
,数据网格视图
也是一个控件。然后在代码背后有事件处理程序
,它们本质上是与控制事件
相关联的方法
因此,当您将单击事件附加到按钮时,在幕后,VB.NET
会创建一个事件处理程序,如下所示:
private void button1_Click(object sender, EventArgs e)
{
}
现在,sender
是一个对象,但实际上传递给它的是DataGrid
。所以和你们的说法相反,在那个点上你们似乎不可能知道点击了什么按钮,你们可以知道是否点击了按钮。如果是,并且您附加了事件处理程序,则会调用它。例如,这将显示带有按钮文本的消息框
:
private void button1_Click(object sender, EventArgs e)
{
var btn = (Button)sender;
MessageBox.Show(btn.Text);
}
因此,如果您想知道是否单击了表单
,请附加单击
事件处理程序:
private void Form1_Click(object sender, EventArgs e)
{
var frm = (Form)sender;
MessageBox.Show(frm.Text);
}
我不确定如何防止RowLeave事件中的按钮单击,但我认为应该使用RowValidating事件来验证DataGridView。假设我们有一个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的值。无法单击该按钮,因为它未通过验证。但是,如果将按钮的CausesValidation
属性设置为False
,则不会触发验证
事件的顺序如下所示:
使用键盘更改焦点时(TAB、SHIFT+TAB和
依此类推),通过调用Select或SelectNextControl方法,或
将ContainerControl.ActiveControl属性设置为当前
窗体中,焦点事件按以下顺序发生:Enter->GotFocus->
离开->验证->验证->失去焦点
使用鼠标或调用焦点更改焦点时
方法,焦点事件按以下顺序发生:Enter->GotFocus
->LostFocus->离开->验证->验证
那么,在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
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 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
任何和所有DGV事件的发送方都将是DGV。总是这样。但是按钮在表单上:如何捕获这些?不敢相信,因为其中一个在dgv上,所以无法知道在dgv之外单击了什么。单击事件和RowLeave事件是两个独立的事件。每个事件都有自己的发送者。在按钮点击事件中,发送者应该是按钮本身。为了更好地理解您的问题,请您向我们提供相关的代码片段,好吗?@Simo谢谢。我是否总是必须在代码前面手动添加4个空格?笨重…我试过了,但不起作用:按钮1\u单击和表单1\u单击都是在RowLeave后触发的。所以在我的例子中,这两个事件永远不会被处理,因为RowLeave(执行RowValidation和其他操作)会阻止按钮的代码被执行。我希望按钮具有优先级,即在行离开之前执行。这些事件是独立的。”DataGridView.RowLeave`在焦点离开DataGridView
中的特定行时发生。当用户单击这些控件时,会出现按钮
或表单
单击。他们彼此无关。如果您从未关注过DataGridView
,FormLeave
甚至不会发生。而且没有理由认为FormLeave
事件上的验证等应该停止触发其他事件。也许你应该展示你的代码。在上面的总结中补充。我仍然不明白你想说什么。当用户单击按钮时发生Click事件,当行选择更改时发生RowLeave。它们并不相互依赖。您的代码在RowLeave之后不会到达按钮事件。你希望它会这样吗?事实并非如此:如果我在RowLeave中的代码不起任何作用,则RowLeave将首先在鼠标单击按钮之后处理,然后,仅在单击事件之后处理。此外,它们以两种方式相互依赖:a)因为存在一个序列:在处理单击之前始终RowLeave;b)RowLeave事件中的代码导致单击未被处理。这就是为什么我希望看到序列行离开,然后单击反转,或者找到一种确定方向的方法