如何基于其子元素是否拥有焦点来为自定义控件添加样式?

10
我们有一个自定义画布,其中有一些特殊的节点,行为很像标准 MDI 应用程序的窗口。期望的行为是,如果“窗口”的任何子控件具有焦点,则该“窗口”被认为是活动的。
现在,IsFocused 属性似乎不会级联,这意味着如果子控件具有焦点,则其容器也不会被设置为“已聚焦”,因此我们不能使用它。出于同样的原因,我们也不能在容器上设置 IsFocused 属性,因为我认为那会从子控件那里夺走它。
我唯一想到的办法是创建一个名为 HasChildWithFocus 的新 DP,然后在代码后台中,监听冒泡事件并设置该标志。不确定是否这是最好的方式。(我们可能将其实现为组合附加属性/附加行为的方式。)
但当然,如果我们能简单地询问一个控件“嘿...你或你的任何子控件都拥有焦点吗?”那就好多了。
所以,你能吗?

我赞同你提出的附加行为的想法,它监听冒泡事件并设置一个附加属性。这是我会做的方式,我想不到其他更好的主意! - ColinE
那么就+1我的问题吧!来嘛...帮个极客出一下主意![smirk](谢谢你的反馈。是啊...那是我能想到的唯一方法。) - Mark A. Donohoe
1个回答

13

您可以直接使用UIElement.IsKeyboardFocusWithin,如下所示:

<Grid>
    <Grid.Resources>
        <Style x:Key="panelStyle" TargetType="Border">
            <Setter Property="BorderBrush" Value="PaleGoldenrod"/>
            <Style.Triggers>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="BorderBrush" Value="PaleGreen"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </Grid.Resources>
    <UniformGrid Columns="2">
        <Border BorderThickness="10" Style="{StaticResource panelStyle}">
            <StackPanel>
                <TextBox Text="TextBox1"/>
                <TextBox Text="TextBox2"/>
            </StackPanel>
        </Border>
        <Border BorderThickness="10" Style="{StaticResource panelStyle}">
            <StackPanel>
                <TextBox Text="TextBox3"/>
                <TextBox Text="TextBox4"/>
            </StackPanel>
        </Border>
    </UniformGrid>
</Grid>

在这个例子中,包含键盘焦点元素的边框使用不同的边框画笔进行了样式化。

太完美了!正是我想要的。(我不知道那个属性。)时间也非常完美,因为我刚开始写附加的东西,现在我不必再写了! :) - Mark A. Donohoe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接