WPF DatePicker LostFocus fires seven times

I have a very simple scenario here. Look at the layout please:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>
    <TextBox Grid.Row="0"></TextBox>
    <DatePicker Grid.Row="1" 
                Name="_datePicker"
                LostFocus="_datePicker_OnLostFocus"></DatePicker>
</Grid>

      

and codebehind:

private void _datePicker_OnLostFocus(object sender, RoutedEventArgs e)
{
    Debug.WriteLine("LostFocuse");
}

      

So the problem is, I take the date and click TextBox

, then the event LostFocus

fires 7 ( seven! ) Times. One, when I DatePicker

really lost focus, when I dialed TextBox

and stayed six times completely, is not explicable to me.

How can I fix this? I only need one fire of this event. Or maybe I can use some other event? I tried LostKeyBoardFocus

with the same result.

+3


source to share


3 answers


LostFocus is a routed event with route strategy set to . By bubbling it means it will bubble up to its parent to the root window until it is handled somewhere explicitly by the install . Bubble

e.Handled = true;

So this means that even when the child control is deactivated, it will bubble up to your datePicker, which is why you see multiple calls to your method .



You can check the property that is returned if the focus is inside your control. Since you are not interested in listening to the child lost focus event, you can check this property in your handler like this and only execute your code when the actual focus is lost on the datePicker: IsKeyboardFocusWithin

private void _datePicker_OnLostFocus(object sender, RoutedEventArgs e)
{
    DatePicker picker = sender as DatePicker;
    if (!picker.IsKeyboardFocusWithin)
    {
        System.Diagnostics.Debug.WriteLine("LostFocuse");
    }
}

      

+4


source


You can add a bool value to test for the first time, and then set e.Handled to true.



bool isFired = false;

private void _datePicker_OnLostFocus(object sender, RoutedEventArgs e)
{
    if (!isFired)
        {
            isFired = true;
        }
        e.Handled = true;

}

      

+1


source


You have described the normal behavior of a .NET UIElement.LostFocus

event
. From the linked page on MSDN:

Occurs when this element loses logical focus.

Note that it says boolean focus ... WPF has two kinds of focus; logical and keyboard. Again from the page:

Logical focus differs from keyboard focus if the focus is intentionally removed through a method call, but the previous keyboard focus exists in a different area. In this case, the keyboard focus remains where it is, and the element where the Focus method is called still receives logical focus.

Finally, why has this event triggered many times? This is because even the children inside it DatePicker

can remove logical focus from it when they are clicked, and it can go back to DatePicker

multiple times in a row when the focus is moved through various inner controls. Once again from the page:

Because this event uses bubbling routing, the element that loses focus can be a child element, rather than the element where the event handler is actually attached.

+1


source







All Articles