How can I style a custom control based on if any of its children have focus?
Asked Answered
D

1

10

We have a custom canvas which has specialized nodes that behave a lot like a standard MDI application's windows. The desired behavior is that if any of the child controls of the "window" have the focus, then that "window" is said to be active.

Now the IsFocused property doesn't seem to cascade, meaning if a child control has the focus, it's container is not also set to 'focused' so we can't use that. For the same reason, we can't set the IsFocused property on the container as I believe that would steal it from the child.

My only thought is to create a new DP called HasChildWithFocus or something like that, then in the code-behind, listen for the bubbled events and set that flag. Not sure that's the best way to go. (We may implement that as a combination attached property/attached behavior kinda thing.)

But of course it would be much better if we could simply ask a control 'Hey... do you or any of your children have the focus?'

So can you?

Deas answered 10/2, 2011 at 5:31 Comment(2)
+1 to your idea of an attached behaviour that listens to the bubbled event and sets an attached property. It is the way I would do it, I can't think of any other bright ideas!Digitoxin
Well then +1 my question! C'mon...help a geek out here! [smirk] (Thanks for your feedback. Yeah... that was the only way I could think of.)Deas
P
13

You can use UIElement.IsKeyboardFocusWithin directly like this:

<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>

In this example the border that contains the element with the keyboard focus is styled with a different border brush.

Predesignate answered 10/2, 2011 at 6:27 Comment(1)
Perfect! Just what I wanted. (Didn't know about that property.) Perfect timing too as I had just started to write the attached stuff so now I don't have to! :)Deas

© 2022 - 2024 — McMap. All rights reserved.