【问题标题】:VB Net Clicking event for controlVB Net Clicking 事件控制
【发布时间】:2023-03-28 14:13:01
【问题描述】:

我有一个这样的用户控件:

在那个控件中有一个 Panel(包括一个 Title 标签)和另一个 Panel(包括 Gridview、一个标签)。

我的问题:如何为这个控件设置点击事件(意味着我可以点击这个控件中的任何地方来执行一个事件)

该控件用于以下用户控件:

感谢您的帮助!

【问题讨论】:

  • 你没有描述你遇到的问题是在浪费人们的时间。网格控件本身对鼠标事件有很多用途,并且在您单击或调整标题大小时不会触发 Click 事件。所以你的控制也不会。您应该尝试解决这个问题是非常值得怀疑的。毕竟,您的控件基本上仍然是一个网格控件,只是添加了一些油漆,因此应该表现得像一个网格控件。
  • @HansPassant 你应该再仔细阅读我的问题。我不浪费人们的时间。谢谢

标签: .net vb.net winforms events controls


【解决方案1】:

您可以通过在每个控件触发单击事件时引发 Click 事件来做到这一点,但这很冗长,如果您添加新控件,则必须记住添加处理程序。

更好的方法是使用递归方法为用户控件中的每个控件添加点击事件处理程序:

Public Class UserControl1
    'declare the event (must shadow as the usercontrol already has it's own click event)
    Public Shadows Event Click(sender As Object, e As EventArgs)

    Private Sub ClickEventHandlerForAllControls(sender As Object, e As EventArgs)
        RaiseEvent Click(sender, e)
    End Sub

    Public Sub New()

        ' This call is required by the designer.
        InitializeComponent()

        ' Add any initialization after the InitializeComponent() call.
        AddClickHandlersForControl(Me)
    End Sub


    Private Sub AddClickHandlersForControl(ctl As Control)
        'add the click event handler for this control
        AddHandler ctl.Click, AddressOf ClickEventHandlerForAllControls
        'if the control has children (e.g. panel, form) then iterate through those and add the click event for each one
        If ctl.HasChildren Then
            For Each childCtl As Control In ctl.Controls
                AddClickHandlersForControl(childCtl)
            Next
        End If
    End Sub
End Class

编辑:正如您所说,您希望能够单击任何地方,包括标题行等。实现此目的的方法是使用全局鼠标挂钩(非托管代码不太理想)。

这是一个工作示例:

Public Class UserControl1

    Private Structure MSLLHOOKSTRUCT
        Public pt As Point
        Public mouseData As Int32
        Public flags As Int32
        Public time As Int32
        Public extra As IntPtr
    End Structure

    Private _mouseHook As IntPtr
    Private Const WH_MOUSE_LL As Int32 = 14
    Private Const LEFT_MOUSE_DOWN = 513
    Private Const LEFT_MOUSE_UP = 514

    Private Delegate Function MouseHookDelegate(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
    <Runtime.InteropServices.MarshalAs(Runtime.InteropServices.UnmanagedType.FunctionPtr)> Private _mouseProc As MouseHookDelegate
    Private Declare Function SetWindowsHookExW Lib "user32.dll" (ByVal idHook As Int32, ByVal HookProc As MouseHookDelegate, ByVal hInstance As IntPtr, ByVal wParam As Int32) As IntPtr
    Private Declare Function UnhookWindowsHookEx Lib "user32.dll" (ByVal hook As IntPtr) As Boolean
    Private Declare Function CallNextHookEx Lib "user32.dll" (ByVal idHook As Int32, ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
    Private Declare Function GetModuleHandleW Lib "kernel32.dll" (ByVal fakezero As IntPtr) As IntPtr

    'declare the event (must shadow as the usercontrol already has it's own click event)
    Public Shadows Event Click(sender As Object, e As EventArgs)

    Private Sub UserControl1_HandleCreated(sender As Object, e As EventArgs) Handles Me.HandleCreated
        HookMouse()
    End Sub

    Private Sub UserControl1_HandleDestroyed(sender As Object, e As EventArgs) Handles Me.HandleDestroyed
        UnHookMouse()
    End Sub

    Public Function HookMouse() As Boolean
        If _mouseHook = IntPtr.Zero Then
            _mouseProc = New MouseHookDelegate(AddressOf MouseHookProc)
            _mouseHook = SetWindowsHookExW(WH_MOUSE_LL, _mouseProc, GetModuleHandleW(IntPtr.Zero), 0)
        End If
        Return _mouseHook <> IntPtr.Zero
    End Function

    Public Sub UnHookMouse()
        If _mouseHook = IntPtr.Zero Then Return
        UnhookWindowsHookEx(_mouseHook)
        _mouseHook = IntPtr.Zero
    End Sub

    Private Function MouseHookProc(ByVal nCode As Int32, ByVal wParam As IntPtr, ByRef lParam As MSLLHOOKSTRUCT) As Int32
        Static downLocation As Point = New Point(-1, -1)

        Select Case wParam.ToInt32
            Case LEFT_MOUSE_DOWN
                downLocation = lParam.pt

            Case LEFT_MOUSE_UP
                'don't raise click event if we have dragged
                If lParam.pt = downLocation Then
                    'check the mouse location is inside the bounding rectangle of the usercontrol
                    Dim usercontrolLocation = New Point(Me.Parent.Location.X + Me.Location.X, Me.Parent.Location.Y + Me.Location.Y)
                    Dim usercontrolRect = New Rectangle(usercontrolLocation, Me.Size)
                    If usercontrolRect.Contains(lParam.pt) Then RaiseEvent Click(Me, New EventArgs())
                End If

        End Select
        Return CallNextHookEx(WH_MOUSE_LL, nCode, wParam, lParam)
    End Function

End Class

您的点击事件将由表单上的用户控件引发:

Public Class Form1

    Private Sub UserControl11_Click(sender As Object, e As EventArgs) Handles UserControl11.Click
        MessageBox.Show("Usercontrol was clicked")
    End Sub

End Class

【讨论】:

  • 感谢您的回答。正如我在上面的答案中评论的那样。我也在使用这个解决方案(递归)。但是,我想点击任何地方,如果我们使用它,我们只需点击 Gridview 的行。我们不能单击作为gridview 的标题或gridview 中的其他位置。无论如何,非常感谢。
  • 感谢@Matt Wilko。我尝试将此解决方案与 Me.Click 一起使用,但没有任何反应。你能告诉我如何使用这个解决方案吗?
  • 这将引发用户控件的点击事件而不是表单
【解决方案2】:

您必须为每个单独的控件添加一个点击事件才能使其工作,但幸运的是您也可以通过循环遍历所有控件来自动执行此操作。

只需将下面的代码添加到您的用户控件中,它就会自动为所有子控件添加/删除任何点击事件:

public new event EventHandler Click {
    add {
        base.Click += value;
        foreach (Control control in Controls) {
            control.Click += value;
        }
    }
    remove {
        base.Click -= value;
        foreach (Control control in Controls) {
            control.Click -= value;
        }
    }
}

参考:

【讨论】:

  • 谢谢,但我已经知道这个解决方案。 Public Sub AddEventForAllControls(control As Control) AddHandler control.Click, AddressOf ShowBGLRecording If (control.Controls.Count &gt; 0) Then For Each item As Control In control.Controls AddEventForAllControls(item) Next End If End Sub 但是,它不适用于 Gridview
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-20
  • 1970-01-01
  • 2012-07-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多