WPF: animation target selection

I am trying to create a simple (I think) animation effect based on a property change in my ViewModel. I would like the target to be a specific text block in the control template of the custom control that inherits from the window.

From the sample articles I've seen, DataTrigger is the easiest way to accomplish this. Window.Triggers doesn't seem to support DataTriggers, which led me to try to apply a trigger in style. The problem I'm currently facing is that I cannot target TextBlock (or any other child control) - what happens, since the code below is that the animation applies to the background of the whole window.

If I completely leave StoryBoard.Target, the effect will be exactly the same.

Is this the right approach with the wrong syntax or is there an easier way to do this?

<Style x:Key="MyWindowStyle" TargetType="{x:Type Window}"> <Setter Property="Template" Value="{StaticResource MyWindowTemplate}"/> <Style.Triggers> <DataTrigger Binding="{Binding ChangeOccurred}" Value="True"> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard BeginTime="00:00:00" Duration="0:0:2" Storyboard.Target="{Binding RelativeSource={RelativeSource AncestorType=TextBlock}}" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> <ColorAnimation FillBehavior="Stop" From="Black" To="Red" Duration="0:0:0.5" AutoReverse="True"/> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> </DataTrigger> </Style.Triggers> </Style> 

Update

I should also mention that I tried to name TextBlock and refer to it through StoryBoard.TargetName (as Timores suggested) and got the error "TargetName property could not be set in Set Style."

+4
source share
2 answers

EDIT: I observed that the TextBlock is in the ControlTemplate your custom window / control. I don’t think it’s possible to target a control in a ControlTemplate from a Storyboard outside this ControlTemplate . However, you can define a property in your custom window, which is then bound to your ChangeOccurred property, and then add a trigger to your ControlTemplate , which will now be called by the custom Control property, rather than the Window ViewModel property (of course, it is indirectly launched by ViewModel, because ChangeOccurred tied to a custom window property, which in turn causes an animation - a complex sentence, I hope you understand). Is this an option? Could you go ?; -)

Maybe some code helps:

 public class MyCustomWindow : Window { public static readonly DependencyProperty ChangeOccurred2 = DependencyProperty.Register(...); public bool ChangeOccurred2 { ... } // ... } 

And some XAML:

 <local:MyCustomWindow ChangeOccurred2="{Binding ChangeOccurred}" ... > <!-- Your content here... --> </local:MyCustomWindow> <!-- Somewhere else (whereever your ControlTemplate is defined) --> <ControlTemplate TargetType="{x:Type local:MyCustomWindow}"> <!-- your template here --> <ControlTemplate.Triggers> <Trigger Property="ChangeOccurred2" Value="True"> <Trigger.EnterActions> <BeginStoryboard> <Storyboard BeginTime="00:00:00" Duration="0:0:2" Storyboard.TargetName="txtWhatever" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> <ColorAnimation FillBehavior="Stop" From="Black" To="Red" Duration="0:0:0.5" AutoReverse="True"/> </Storyboard> </BeginStoryboard> </Trigger.EnterActions> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> 

Note. I named the Window ChangeOccurred2 property because I wanted it to be distinguishable from the ViewModel ChangeOccurred . Of course, you should choose the best name for this property. However, I do not have enough background for such a solution.


My old answer:

So you want to animate a TextBlock that is in the contents of a (custom) window ?!

Why do you want to set the style in the window, and not in the TextBlock itself? Maybe you should try something like this (don't check this out!):

 <local:MyCustomWindow ... > <!-- ... --> <TextBlock x:Name="textBlockAnimated" ... > <TextBlock.Style> <Style TargetType="{x:Type TextBlock}"> <Style.Triggers> <DataTrigger Binding="{Binding ChangeOccurred}" Value="True"> <DataTrigger.EnterActions> <BeginStoryboard> <Storyboard BeginTime="00:00:00" Duration="0:0:2" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> <ColorAnimation FillBehavior="Stop" From="Black" To="Red" Duration="0:0:0.5" AutoReverse="True"/> </Storyboard> </BeginStoryboard> </DataTrigger.EnterActions> </DataTrigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> <!-- ... --> </local:MyCustomWindow> 

{Binding ChangeOccurred} may not be enough. You may need to add a DataContext to a TextBlock or add a RelativeSource or something else.

+4
source

Is TextBlock in MyWindowTemplate?

If so, give TextBlock a name and use Storyboard.TargetName to refer to it.

See another question in SO

0
source

Source: https://habr.com/ru/post/1308401/


All Articles