J-man
J-man

Reputation: 1833

WPF Animation on TextBox Border On IsMouseOver when Not Focused

I am implementing custom styles for the TextBox type in a WPF app I am working on, and I want to implement different animations for when the cursor is over the TextBox, and when the TextBox is actually focused. How my code currently works is the IsMouseOver trigger fires and starts the animation even when the TextBox already has focus. I do not want this, I want the IsMouseOver animation to play only when the TextBox is not focused and when the user hovers over the TextBox. Is this possible in XAML?

Here is my existing code:

<Style TargetType="TextBox">
    <Setter Property="BorderBrush" Value="Gray" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBoxBase}">
                <Border x:Name="PART_Border" 
                        Background="{TemplateBinding Background}"  
                        BorderBrush="{TemplateBinding BorderBrush}" 
                        BorderThickness="{TemplateBinding BorderThickness}" 
                        CornerRadius="4">
                    <ScrollViewer x:Name="PART_ContentHost"/>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" TargetName="PART_Border" />
                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                    </Trigger>
                    <Trigger Property="IsFocused" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="PART_Border" Storyboard.TargetProperty="BorderBrush.Color" To="#0079CB" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="PART_Border" Storyboard.TargetProperty="BorderBrush.Color" To="#CBCBCB" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.ExitActions>
                    </Trigger>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Trigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="PART_Border" Storyboard.TargetProperty="BorderBrush.Color" To="#5A5A5A" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions>
                        <Trigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="PART_Border" Storyboard.TargetProperty="BorderBrush.Color" To="#CBCBCB" />
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.ExitActions>
                    </Trigger>
                    <Trigger Property="Validation.HasError" Value="True">
                        <Setter Property="FocusManager.FocusedElement" Value="{Binding RelativeSource={RelativeSource Self}}"/>
                        <Setter Property="BorderThickness" Value="0" />
                    </Trigger>
                    <Trigger Property="Width" Value="Auto">
                        <Setter Property="MinWidth" Value="100"/>
                    </Trigger>
                    <Trigger Property="Height" Value="Auto">
                        <Setter Property="MinHeight" Value="20"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Thanks!

Upvotes: 2

Views: 1292

Answers (1)

Manfred Radlwimmer
Manfred Radlwimmer

Reputation: 13394

I want the IsMouseOver animation to play only when the TextBox is not focused and when the user hovers over the TextBox.

(Emphasis mine)

It's actually just a small adjustment to your existing code. You need to use a MultiTrigger instead of the simple Trigger to account for IsMouseOver and the Focus. Depending on your exact requirements you might want to use IsKeyboardFocusWithin, IsKeyboardFocused or IsFocused for the second condition.

<MultiTrigger>
    <MultiTrigger.Conditions>
        <Condition Property="IsMouseOver" Value="True"/>
        <Condition Property="IsKeyboardFocusWithin" Value="False"/>
    </MultiTrigger.Conditions>
    <MultiTrigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="PART_Border" 
                  Storyboard.TargetProperty="BorderBrush.Color" To="#5A5A5A" />
            </Storyboard>
        </BeginStoryboard>
    </MultiTrigger.EnterActions>
    <MultiTrigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <ColorAnimation Duration="0:0:0.15" Storyboard.TargetName="PART_Border" 
                  Storyboard.TargetProperty="BorderBrush.Color" To="#CBCBCB" />
            </Storyboard>
        </BeginStoryboard>
    </MultiTrigger.ExitActions>
</MultiTrigger>

Upvotes: 1

Related Questions