Feeds:
Posts
Comments

Posts Tagged ‘LostFocus’

Try to trap for the focus changed events (GotFocus and LostFocus) in Silverlight in a container control; I dare you! 😉 You’ll quickly realize that all the GotFocus and LostFocus events of all the children controls and their children controls fire on the container. This is of course due to event bubbling (which is a good thing). But, it makes it awefully hard to tell when the container itself is getting focus (after not having it) or loosing focus because something outside your container now has it.

For example: Create a StackPanel (MyContainer) with 2 controls in it and put that next to another control (the button)…

   <StackPanel>
      <StackPanel x:Name=”MyContainer”>
         <TextBox/>
         <TextBox/>
      </StackPanel>
      <Button Content=”button3″/>
   </StackPanel>

Now put debug statements in MyContainer’s GotFocus and LostFocus events…

Private Sub MyContainer_GotFocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyContainer.GotFocus
    Diagnostics.Debug.WriteLine("MyContainer_GotFocus")
End Sub
 
Private Sub MyContainer_LostFocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyContainer.LostFocus
    Diagnostics.Debug.WriteLine("MyContainer_LostFocus")
End Sub

Hmm, looks like our container lost focus… but it didn’t!? Focus is simply on another child in the same container. The events are firing like this because the children controls are bubbling up their events to the container so it looks like the container is loosing and getting focus each time. So how do we determine if focus has actually been given to a control outside the container or if focus is still inside the container?

The answer is not that hard. all we need to do is determine if at the time the LostFocus event is fired, if the item that has focus is a child of our container. And you can use the System.Windows.Input.FocusManager.GetFocusedElement method to determine which object has focus. I created a nice little IsRelated function to help determine who is a decendent.

Private Shared Function IsRelated(ByVal Child As Object, ByVal Parent As Object) As Boolean
    Return Child Is Parent OrElse (TypeOf Child Is FrameworkElement _
        AndAlso _
        IsRelated(DirectCast(Child, FrameworkElement).Parent, Parent))
End Function
 
Private HasFocus As Boolean
 
Private Sub MyContainer_GotFocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyContainer.GotFocus
    If Not HasFocus Then
        HasFocus = True
        Diagnostics.Debug.WriteLine("MyContainer_GotFocus")
    End If
End Sub
 
Private Sub MyContainer_LostFocus(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles MyContainer.LostFocus
    If Not IsRelated(System.Windows.Input.FocusManager.GetFocusedElement, _
            MyContainer) Then
        HasFocus = False
        Diagnostics.Debug.WriteLine("MyContainer_LostFocus")
    End If
End Sub

And that’s all there is to it. Happy coding!

Read Full Post »