DataGridView.RowLeave在“表单”按钮之前触发。

时间:2018-09-06 16:58:21

标签: vb.net forms datagridview mouseclick-event

我在任何地方都找不到有关此的任何信息: 我有一个带有StorageFile timeStampFile = timeStampFiles.First(f => f.Name == sourceFile.Name); Debug.WriteLine("TS FILE DATE=" + timeStampFile.DateCreated.DateTime); //TS FILE DATE=9/6/2018 7:14:43 PM StorageFile createdCopy = await timeStampFile.CopyAsync(destinationFolder); Debug.WriteLine("COPIED FILE DATE=" + createdCopy.DateCreated.DateTime); //COPIED FILE DATE=9/6/2018 7:36:30 PM 和几个按钮的表单。选择 datagridview 的一行,然后单击一个按钮(在表单上)时,string connectionString = (some condition) ? ConfigurationManager.ConnectionStrings["REMOTE"].ConnectionString : ConfigurationManager.ConnectionStrings["DBCS"].ConnectionString; using(var con = new SqlConnection(connectionString)) { // code using your SqlConnection instance } 会先触发。它甚至在Click或MouseClick之前触发。

这是有道理的,但问题在于DataGridView发件人 DataGridView ,而不是按钮。因此似乎无法知道此时单击了哪个按钮,因为sender和e都引用了DataGridView,而不是Form或Buttons。

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

因此,在 RowLeave 做其他事情之前,有什么方法可以知道用户单击的位置(对我而言,导致 Button.Click永远不会被处理) ,还是从RowLeave内部?

dgv.RowLeave

3 个答案:

答案 0 :(得分:0)

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

因此Event被附加到ControlButtonControlDataGridView也是如此。然后,在后面的代码中,您拥有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);
}

答案 1 :(得分: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的值。您无法单击该按钮,因为它无法通过验证。但是,如果将Button的{​​{1}}属性设置为CausesValidation,则不会触发验证。

根据this link的事件顺序如下:

  

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

     

使用鼠标或调用Focus来更改焦点时   方法,焦点事件按以下顺序发生:Enter-> GotFocus   -> LostFocus->离开->验证->已验证

答案 2 :(得分: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

这有点麻烦,但是在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