MultiTriggers using the same property in XAML

235 Views Asked by At

I'm actually overriding the default ControlTemplate of the TextBox and in order to do what I want, I need to trigger two animations when the TextBox loose the focus and it's text is empty. In order to do that I'm using a MultiTrigger with two conditions like this:

(I'll use an animation on the FontSize for the example)

<MultiTrigger>
  <MultiTrigger.Conditions>
    <Condition Property="IsFocused" Value="False"/>
    <Condition Property="Text" Value="{x:Static sys:String.Empty}"/>
  </MultiTrigger.Conditions>
  <MultiTrigger.EnterActions>
    <BeginStoryboard>
      <Storyboard>
        <DoubleAnimation Storyboard.TargetName="Title" Storyboard.TargetProperty="FontSize" From="9" To="120" Duration="0:0:2">
          <DoubleAnimation.EasingFunction>
            <QuinticEase EasingMode="EaseInOut"/>
          </DoubleAnimation.EasingFunction>
        </DoubleAnimation>
      </Storyboard>
    </BeginStoryboard>
  </MultiTrigger.EnterActions>
</MultiTrigger>

The thing is that, the animation is triggered at the TextBox instantiation because the TextBox is not focused and the Text is empty. So we can say that the animation and the MultiTrigger are working, but when I focus the TextBox once (the GotFocus resets the FontSize), on the LostFocus the animation is not triggered anymore.

BUT if I replace the whole MultiTrigger.EnterActions by this:

<MultiTrigger.Setters>
  <Setter Property="Background" Value="Red"/>
</MultiTrigger.Setters>

Everything is working like a charm. I mean that the background is red at the begining, white on the GotFocus and red again on the LostFocus.

I might by misunderstanding the way we have to use the EnterActions but there's not that much documentation on MultiTriggers out there. Do you know why the animation isn't triggered anymore after the first time?

And by the way, is there a better way than Value="{x:Static sys:String.Empty}"to check if the Text property is empty?

EDIT : In my ControlTemplate.Triggers I'm already using two EventTriggers, one is routed to the GotFocus event and the other one to the LostFocus event. I saw on the MSDN that EnterActions does not apply to the EventTrigger, so I tried to get rid of both of my EventTriggers and now it works.

The thing is that I used a MultiTrigger because I needed to check if the Text was empty on the LostFocus but may be there is a way to put that condition in an EventTrigger?

EDIT #2: AS @Satish Pai asked, here is the full ControlTemplate in which I replaced the EventTriggers by a MutliTrigger because, as I said, they seems to be incompatible.

<ControlTemplate TargetType="{x:Type TextBox}">
    <Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="14"/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <TextBlock x:Name="Title" Text="{TemplateBinding ToolTip}" Margin="8,14,0,0" Grid.Row="0" Grid.RowSpan="2" Foreground="{StaticResource TextBox.Static.Border}"></TextBlock>
            <ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden" Grid.Row="1"/>
            <Rectangle x:Name="UnfocusedUnderLine" Fill="{StaticResource TextBox.Static.Border}" Height="6" Margin="0,1,0,0" Grid.Row="2"/>
            <Rectangle x:Name="UnderLine" Fill="{StaticResource TextBox.Focus.Border}" Height="6" Margin="0,1,0,0" Grid.Row="2" Width="0"/>
        </Grid>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Opacity" TargetName="border" Value="0.56"/>
        </Trigger>
        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
        </Trigger>
        <Trigger Property="IsKeyboardFocused" Value="true">
            <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
        </Trigger>
        <MultiTrigger x:Name="FocusChanged">
            <MultiTrigger.Conditions>
                <Condition Property="IsFocused" Value="True"/>
            </MultiTrigger.Conditions>
            <MultiTrigger.EnterActions> <!--GotFocus-->
                <BeginStoryboard>
                    <Storyboard>
                        <!--Change UnderLine Color-->
                        <DoubleAnimation Storyboard.TargetName="UnderLine" Storyboard.TargetProperty="Width" From="0" To="500" Duration="0:0:0.25">
                            <DoubleAnimation.EasingFunction>
                                <QuinticEase EasingMode="EaseInOut"/>
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>

                    
                    <!--Move Title Up-->
                    <ThicknessAnimation From="8,14,0,0" To="0,0,0,0" Duration="0:0:0.25" Storyboard.TargetName="Title" Storyboard.TargetProperty="Margin" AutoReverse="False" >
                        <ThicknessAnimation.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </ThicknessAnimation.EasingFunction>
                    </ThicknessAnimation>
                    
                    <!--Decrease Title Size-->
                    <DoubleAnimation Storyboard.TargetName="Title"
                                     Storyboard.TargetProperty="FontSize"
                                     From="12"
                                     To="9"
                                     Duration="0:0:0.25">
                        <DoubleAnimation.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </DoubleAnimation.EasingFunction>
                    </DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </MultiTrigger.EnterActions>
        <MultiTrigger.ExitActions>  <!--LostFocus-->
            <BeginStoryboard>
                <Storyboard>
                    
                    <!--Change UnderLine Color-->
                    <DoubleAnimation Storyboard.TargetName="UnderLine"
                                     Storyboard.TargetProperty="Width"
                                     From="500"
                                     To="0"
                                     Duration="0:0:0.2">
                        <DoubleAnimation.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </DoubleAnimation.EasingFunction>
                    </DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </MultiTrigger.ExitActions>
    </MultiTrigger>
    <MultiTrigger x:Name="LostFocusAndEmptyText">
        <MultiTrigger.Conditions>
            <Condition Property="Text" Value="{x:Static sys:String.Empty}"/>
        </MultiTrigger.Conditions>
        <MultiTrigger.EnterActions>
            <BeginStoryboard>
                <Storyboard>
                    <!--Move Title Down-->
                    <ThicknessAnimation From="0,0,0,0" To="8,14,0,0" Duration="0:0:0.2" Storyboard.TargetName="Title" Storyboard.TargetProperty="Margin" AutoReverse="False" >
                        <ThicknessAnimation.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </ThicknessAnimation.EasingFunction>
                    </ThicknessAnimation>

                    <!--Increase Title Size-->
                    <DoubleAnimation Storyboard.TargetName="Title"
                                     Storyboard.TargetProperty="FontSize"
                                     From="9"
                                     To="12"
                                     Duration="0:0:0.2">
                        <DoubleAnimation.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </DoubleAnimation.EasingFunction>
                    </DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </MultiTrigger.EnterActions>
    </MultiTrigger>
    <!--LostFocusWithEmptyText-->
</ControlTemplate.Triggers>
</ControlTemplate>

The thing is that both of the MultiTiggers are referring to the same IsFocused property and they don't wanna work together. If I delete the LostFocusAndEmptyText trigger it works, but I really need to differentiate the case where I loose the focus with an empty text and without.

Any suggestion on how to achieve that?

1

There are 1 best solutions below

0
On

Chage your TiTle TextBlock init state. Marging="0,0,0,0" FontSize = "9"

<TextBlock x:Name="Title" Text="{TemplateBinding ToolTip}" FontSize="9" Margin="0,0,0,0" Grid.Row="0" Grid.RowSpan="2" 

use Animation's property 'FillBehavior' set to "Stop". and remove animation's property 'From' in EventTrigger. good luck!

<ControlTemplate.Triggers>
    <Trigger Property="IsEnabled" Value="false">
        <Setter Property="Opacity" TargetName="border" Value="0.56"/>
    </Trigger>
    <Trigger Property="IsMouseOver" Value="true">
        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
    </Trigger>
    <Trigger Property="IsKeyboardFocused" Value="true">
        <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
    </Trigger>
    <EventTrigger RoutedEvent="GotFocus">
        <BeginStoryboard>
            <Storyboard>
                <ThicknessAnimation To="0,0,0,0" Duration="0:0:0.25"
                                        Storyboard.TargetName="Title" FillBehavior="Stop" 
                                        Storyboard.TargetProperty="Margin" AutoReverse="False" >
                    <ThicknessAnimation.EasingFunction>
                        <QuinticEase EasingMode="EaseInOut"/>
                    </ThicknessAnimation.EasingFunction>
                </ThicknessAnimation>

                <DoubleAnimation Storyboard.TargetName="Title"
                                Storyboard.TargetProperty="FontSize" FillBehavior="Stop" 
                                To="9"
                                Duration="0:0:0.25">
                    <DoubleAnimation.EasingFunction>
                        <QuinticEase EasingMode="EaseInOut"/>
                    </DoubleAnimation.EasingFunction>
                </DoubleAnimation>
            </Storyboard>
        </BeginStoryboard>
    </EventTrigger>
    <MultiTrigger x:Name="LostFocusAndEmptyText">
        <MultiTrigger.Conditions>
            <Condition Property="Text" Value="{x:Static sys:String.Empty}"/>
            <Condition Property="IsFocused" Value="False"/>
        </MultiTrigger.Conditions>
        <Setter TargetName="Title"  Property="FontSize"  Value="12"/>
        <Setter TargetName="Title"  Property="Margin"  Value="8,14,0,0"/>
        <MultiTrigger.EnterActions>
            <BeginStoryboard>
                <Storyboard>
                    <ThicknessAnimation From="0,0,0,0" To="8,14,0,0" Duration="0:0:0.25" 
                                        FillBehavior="Stop"
                                        Storyboard.TargetName="Title" Storyboard.TargetProperty="Margin" 
                                        AutoReverse="False" >
                        <ThicknessAnimation.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </ThicknessAnimation.EasingFunction>
                    </ThicknessAnimation>
                    <DoubleAnimation Storyboard.TargetName="Title"
                                Storyboard.TargetProperty="FontSize"
                                FillBehavior="Stop"
                                To="12" From="9"
                                Duration="0:0:0.2">
                        <DoubleAnimation.EasingFunction>
                            <QuinticEase EasingMode="EaseInOut"/>
                        </DoubleAnimation.EasingFunction>
                    </DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </MultiTrigger.EnterActions>
    </MultiTrigger>                        
</ControlTemplate.Triggers>