Results 1 to 3 of 3

Thread: Overriding Control.LostFocus

  1. #1
    pizzaboy is offline VB.NET Forum Enthusiast
    .NET Framework
    .NET 4.0
    Join Date
    Jan 2008
    Posts
    57
    Reputation
    69

    Overriding Control.LostFocus

    I have a custom control, that shows a panel (similar to a combobox dropdown, or toolbar menu list) when it has focus.

    When the control loses focus, it raises an event to close the panel (make it invisible).

    The problem I'm having is that the panel has options to edit the custom control. How do I override the lostfocus, so that when focus is switched to either the custom control OR any controls in the panel I can ignor the Raiseevent.


    I'm currently doing this:
    Code:
    Custom control:
        Public Event ConfirmSelection()
        Private Sub txtText_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtText.LostFocus
            RaiseEvent ConfirmSelection()
        End Sub
    
    
    The EventHandler for the panel:
        Private Sub ConfirmSelection() Handles InputBox.ConfirmSelection
            If Not (HaveFocus()) Then
                    Me.Visible = False
            End If
        End Sub
        Private Function HaveFocus() As Boolean
            Dim result As Boolean = False
            For Each itm As Control In Me.Controls
                If itm.Focused Then
                    result = True
                    Exit For
                End If
            Next
            Return result
        End Function

    When I click on something inside the panel, the custom control raises the txtText.LostFocus which is fine, I presume the problem is that the focus has not yet been passed to a new control, so the Me.Controls.Control.Focused is not set to anything.

    Any suggestions on how to keep the panel open?


    Any help would be greatly appreciated.

    Thanks.
    Last edited by pizzaboy; 08-08-2010 at 4:00 AM.

  2. #2
    pizzaboy is offline VB.NET Forum Enthusiast
    .NET Framework
    .NET 4.0
    Join Date
    Jan 2008
    Posts
    57
    Reputation
    69
    Nasty, nasty, nasty!!!

    Turns out that "For Each itm As Control In Me.Controls" was not sufficient as child controls contained in controls were not getting referenced...

    Resolved the problem, but surely there must be a better way of handling this problem?


    Code:
    Custom control:
        Public Event ConfirmSelection()
        Private Sub txtText_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtText.LostFocus
            RaiseEvent ConfirmSelection()
        End Sub
    
    
    The EventHandler for the panel:
        Private Sub ConfirmSelection() Handles InputBox.ConfirmSelection
            If Not (HaveFocus(Me)) Then
                    Me.Visible = False
            End If
        End Sub
    
    
    Check to see if Focus has been passed into a control on the panel:
        Private Function HaveFocus(ByVal ctl As Control) As Boolean
            Dim result As Boolean = False
            If ctl.Focused Then
                result = True
            Else
                If ctl.HasChildren Then
                    For Each itm As Control In ctl.Controls
                        If HaveFocus(itm) Then
                            result = True
                            Exit For
                        End If
                    Next
                End If
            End If
            Return result
        End Function
    
    
    In the Panel.Load() event, handle all the LostFocus() events for EVERY control on the panel!!!:
        Private Sub ctlDropDown_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            AddLostFocusHandler(Me)
        End Sub
    
        Private Sub AddLostFocusHandler(ByVal ctl As Control)
            For Each itm As Control In ctl.Controls
                AddHandler itm.LostFocus, AddressOf ConfirmSelection
    
                If itm.HasChildren Then AddLostFocusHandler(itm)
            Next
        End Sub

  3. #3
    JohnH's Avatar
    JohnH is offline VB.NET Forum Moderator
    .NET Framework
    .NET 4.0
    Join Date
    Dec 2005
    Location
    Norway
    Posts
    14,205
    Reputation
    2369
    Control.ContainsFocus Property (System.Windows.Forms) this has same effect as your HaveFocus recursive method.
    Overriding Control.LostFocus
    What you're doing there is handling an event, not overriding. In control development it is better practice to override the corresponding OnSomething protected methods. Type 'Overrides' keyword and the list of overridable members present itself by intellisense.
    Public Event ConfirmSelection()
    To provide default sender/e parameters it should be:
    Code:
    Public Event ConfirmedSelection As EventHandler
    I think the naming should be ConfirmingSelection or ConfirmedSelection perhaps.

    Following common event pattern this should also be accompanied with a corresponding OnConfirmedSelection protected member:
    Code:
    Protected Overridable Sub OnConfirmedSelection(ByVal e As EventArgs)        
        RaiseEvent ConfirmedSelection(Me, e)    
    End Sub
    internal calling:
    Code:
    OnConfirmedSelection(EventArgs.Empty)
    Design Guidelines for Developing Class Libraries

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Harvest time tracking