Home > Enterprise >  IsKeyboardFocusWithin Popup
IsKeyboardFocusWithin Popup

Time:10-11

I use the IsKeyboardFocusWithin value to set IsSelected to ListViewItem in my layout. So far it worked fine, until I discovered, that the Popup within my item doesn't pass IsKeyboardFocus value to its parent, making this property set to false in Popup's ancestors, while the Popup and its children have set it to true.

This issue reproduces when you click on some of the Popup's children like Button or ListBoxItem.

I've created a simple project to reproduce it:

When you click on the button, IsKeyboardFocusWithin set to true in the button, in its parent Popup, but no further.

Is there a way for the Popup's ancestors to receive its IsKeyboardFocusWithin value?

<Window
    x:Class="PopupDemo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:PopupDemo"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="MainWindow"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <Popup IsOpen="True" StaysOpen="True">
            <Button Content="Test" />
        </Popup>
    </Grid>

    <Window.Style>
        <Style TargetType="{x:Type Window}">
            <Style.Triggers>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="Background" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Window.Style>
</Window>

CodePudding user response:

Popup, ToolTip, ContextMenu - they create their own little Window.
Therefore, these elements are not children of the one for which they are created. And when a Window with these elements pops up, the focus goes to this Window.
And since the focus has shifted to it, then, accordingly, it is not in the main Window.

In your reconciliation, this can be solved through an additional trigger that determines the Popup display.
But such a solution is very specific for the task, and may not be suitable for another.
For example, for ListView, ListBox - this will not work.
For them, you do not need to create a trigger, but change the value of the IsSelected property.

    <Grid>
        <Popup x:Name="popup" IsOpen="True" StaysOpen="True">
            <Button Content="Test" />
        </Popup>
    </Grid>

    <Window.Style>
        <Style TargetType="{x:Type Window}">
            <Style.Triggers>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="Background" Value="Red" />
                </Trigger>
                <DataTrigger Binding="{Binding IsKeyboardFocusWithin, ElementName=popup}"  Value="True">
                    <Setter Property="Background" Value="Red" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Window.Style>
  • Related