What I need to do:
At the time of the event GotFocus
, no event of MouseEnter
and MouseLeave
run.
After the events LostFocus
, MouseEnter
and MouseLeave
become active again.
Given the needs, I've written the following code, but the commands for Pause
and Resume
do not work.
<ControlTemplate x:Key="SpecialNumber" TargetType="{x:Type TextBox}">
<Grid>
<Image x:Name="SpecialBg" Style="{DynamicResource CallStatusSpecialBg}"/>
<Image x:Name="SpecialIBeam" Style="{DynamicResource CallStatusSpecialIBeam}" Source="../image/I-beam-b.png"/>
<TextBox x:Name="SpecialText" Style="{DynamicResource CallStatusSpecialNumberText}" Text="5555" />
</Grid>
<ControlTemplate.Resources>
<Storyboard x:Key="Hide">
<DoubleAnimation Storyboard.TargetName="SpecialBg" Storyboard.TargetProperty="Opacity" Duration="0:0:0.4" To="0" />
<DoubleAnimation Storyboard.TargetName="SpecialIBeam" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="0" />
<DoubleAnimation Storyboard.TargetName="SpecialText" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="0" />
</Storyboard>
<Storyboard x:Key="ShowHalf">
<DoubleAnimation Storyboard.TargetName="SpecialBg" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="1" />
<DoubleAnimation Storyboard.TargetName="SpecialIBeam" Storyboard.TargetProperty="Opacity" Duration="0:0:0.4" To="1" />
<DoubleAnimation Storyboard.TargetName="SpecialText" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="0.01" />
</Storyboard>
<Storyboard x:Key="Show">
<DoubleAnimation Storyboard.TargetName="SpecialBg" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="1" />
<DoubleAnimation Storyboard.TargetName="SpecialIBeam" Storyboard.TargetProperty="Opacity" Duration="0:0:0.4" To="1" />
<DoubleAnimation Storyboard.TargetName="SpecialText" Storyboard.TargetProperty="Opacity" Duration="0:0:0.2" To="1" />
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<EventTrigger SourceName="SpecialText" RoutedEvent="UIElement.MouseEnter" >
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource ShowHalf}" x:Name="SpecialTextMouseEnter"/>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger SourceName="SpecialText" RoutedEvent="UIElement.MouseLeave" >
<EventTrigger.Actions>
<BeginStoryboard Storyboard="{StaticResource Hide}" x:Name="SpecialTextMouseLeave"/>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger SourceName="SpecialText" RoutedEvent="UIElement.GotFocus" >
<EventTrigger.Actions>
<PauseStoryboard BeginStoryboardName="SpecialTextMouseLeave" />
<PauseStoryboard BeginStoryboardName="SpecialTextMouseEnter" />
<BeginStoryboard Storyboard="{StaticResource Show}" x:Name="SpecialTextGotFocus"/>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger SourceName="SpecialText" RoutedEvent="UIElement.LostFocus" >
<EventTrigger.Actions>
<ResumeStoryboard BeginStoryboardName="SpecialTextMouseLeave" />
<ResumeStoryboard BeginStoryboardName="SpecialTextMouseEnter" />
<BeginStoryboard Storyboard="{StaticResource Hide}" x:Name="SpecialTextLostFocus"/>
</EventTrigger.Actions>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
Instead of using the EventTrigger
s, you can use a simple Trigger
with a couple of MultiTrigger
s that allow you to define a complex condition.
I have a solution for you.
First of all, set the default Opacity
of your elements to 0, because this will be the correct initial state:
<Image Opacity="0"/>
<Image Opacity="0" />
<TextBox Opacity="0" />
Then, define the triggers that will do the job:
<ControlTemplate.Triggers>
<!-- This trigger will unconditionally show the elements,
if the text box has keyboard focus,
and hide them, if the text box is not focused -->
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Show}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource Hide}"/>
</Trigger.ExitActions>
</Trigger>
<!-- This trigger will partly show the elements, if the mouse cursor
is over the text box, but it is not focused. If it's focused, then
the previous trigger has already done its job -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsKeyboardFocusWithin" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource ShowHalf}" x:Name="ShowHalfStoryboard" />
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="ShowHalfStoryboard"/>
</MultiTrigger.ExitActions>
</MultiTrigger>
<!-- This trigger will hide the elements, if the mouse cursor
is outside the text box, and it is not focused. If it's focused, then
the first trigger has already done its job. If it's not focused and
the cursor is over the text box, then the previous trigger works. -->
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="False" />
<Condition Property="IsKeyboardFocusWithin" Value="False"/>
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource Hide}" x:Name="HideStoryboard" />
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<RemoveStoryboard BeginStoryboardName="HideStoryboard"/>
</MultiTrigger.ExitActions>
</MultiTrigger>
</ControlTemplate.Triggers>