2016-07-21 3 views
0

ich eine Benutzersteuerung wie diese:VB Net Einen Klick Ereignis für die Steuerung

user control 1

In dieser Kontrolle hat einen Panel (einen Titel Label) und ein anderes Panel (gehört Gridview, ein Etikett).

Meine Frage: Wie setzen für dieses Steuerelement Ereignis klicken (Mittel kann ich überall in dieser Steuerung Sie auf ein Ereignis auszuführen)

, dass die Steuerung wird unter Benutzersteuerung verwendet in: user control 2

Vielen Dank für Ihre Portion!

+0

Sie sind Menschen Zeit verschwenden nicht beschreiben Sie das Problem aufgetreten. Das Grid-Steuerelement wird häufig für Mausereignisse verwendet und löst kein Click-Ereignis aus, wenn Sie z. B. auf eine Kopfzeile klicken oder deren Größe ändern. Also wird deine Kontrolle auch nicht. Es ist sehr zweifelhaft, dass Sie * versuchen * sollten, dieses Problem zu beheben. Schließlich ist Ihre Kontrolle immer noch eine Rastersteuerung, nur etwas Farbe hinzugefügt, und sollte sich daher wie eine Rastersteuerung verhalten. –

+0

@HansPassant sollten Sie meine Frage erneut sorgfältig lesen. Ich verschwende nicht die Zeit der Leute. Danke –

Antwort

2

Sie können dies durch Ra tun Es gibt ein Click-Ereignis, wenn jedes Steuerelement ein Klickereignis auslöst. Dies ist jedoch langwierig. Wenn Sie ein neues Steuerelement hinzufügen, müssen Sie daran denken, den Handler hinzuzufügen.

Eine bessere Möglichkeit ist die Click-Ereignishandler für jede Steuerung in der Benutzersteuerung unter Verwendung eines rekursiven Methode hinzufügen:

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 

EDIT: Wie Sie gesagt haben, dass Sie überall in der Lage sein wollen, einschließlich Header klicken Zeilen, usw. Der Weg dazu ist mit einem globalen Maus-Hook (unmanaged Code so weniger wünschenswert).

Hier ist ein funktionierendes Beispiel dafür:

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 

Ihre Click-Ereignis wird von der usercontrolon Ihre Form erhöht werden:

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 
+0

Vielen Dank für Ihre Antwort zu arbeiten. Wie ich in der obigen Antwort kommentiert habe. Ich benutze auch diese Lösung (rekursiv). Allerdings möchte ich irgendwo klicken, wenn wir dies verwenden, können wir einfach auf Zeilen von Gridview klicken. Wir können nicht als Kopfzeile von Gridview oder einem anderen Ort in Gridview klicken. Wie auch immer, vielen Dank. –

+0

Sehen Sie meine Bearbeitung, wie dies zu tun ist –

+0

Danke @Matt Wilko. Ich habe versucht, diese Lösung mit Me.Click, aber nichts passiert. Können Sie mir sagen, wie Sie diese Lösung verwenden können? –

2

Sie müssen jedem einzelnen Steuerelement ein Klickereignis hinzufügen, damit das funktioniert, aber zum Glück können Sie das auch automatisch tun, indem Sie alle Steuerelemente durchlaufen.

Fügen Sie einfach den Code unten, um Ihre Benutzersteuerung und es wird automatisch hinzufügen/entfernen Sie alle Click-Ereignisse an alle untergeordneten Steuerelemente:

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; 
     } 
    } 
} 

Referenzen:

+0

Danke dir, aber ich kenne diese Lösung schon. 'Public Sub AddEventForAllControls (Kontrolle As Control) AddHandler control.Click, AddressOf ShowBGLRecording If (control.Controls.Count> 0) Then für jedes Element als Kontrolle in Kontrolle.Steuert AddEventForAllControls (Artikel) Weiter End If End Sub' Es ist jedoch nicht mit Gridview –