Phi*_*ler 5 data-binding wpf animation
我试图根据我的ViewModel中的属性更改创建一个简单的(我认为)动画效果.我希望目标成为自定义控件的控件模板中的特定文本块,该控件继承自Window.
从我看过的文章示例中,DataTrigger是实现此目的的最简单方法.Window.Triggers似乎不支持DataTriggers,这导致我尝试在样式中应用触发器.我目前遇到的问题是我似乎无法将TextBlock(或任何其他子控件)作为目标 - 下面的代码是将动画应用于整个窗口的背景.
如果我完全放弃StoryBoard.Target,效果是完全一样的.
这是使用错误语法的正确方法,还是有更简单的方法来实现这一点?
<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>
Run Code Online (Sandbox Code Playgroud)
更新
还应该提到我试图命名TextBlock并通过StoryBoard.TargetName引用它(正如Timores建议的那样),并得到错误"无法在Style Setter上设置TargetName属性".
编辑:我有监督的事实,TextBlock
就是在ControlTemplate
您的自定义窗口/控制.我不认为这是有可能的目标控制范围内的ControlTemplate
从Storyboard
外面的这个ControlTemplate
.你可以在你的自定义窗口然而定义属性,你那么数据绑定到你的ChangeOccurred
属性,然后触发添加到您ControlTemplate
现在将获得由定制控件的属性触发,而不是窗口的视图模型的财产(当然,间接地是由触发ViewModel因为ChangeOccurred
绑定到自定义Window的属性,而后者又触发动画 - 呃,复杂的句子,希望你理解.这是一个选择吗?你能跟着吗?;-)
也许一些代码有帮助:
public class MyCustomWindow : Window
{
public static readonly DependencyProperty ChangeOccurred2 = DependencyProperty.Register(...);
public bool ChangeOccurred2 { ... }
// ...
}
Run Code Online (Sandbox Code Playgroud)
还有一些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>
Run Code Online (Sandbox Code Playgroud)
注意:我命名了Window的属性,ChangeOccurred2
因为我希望它可以与ViewModel的ChangeOccurred
属性区分开来.当然,您应该为此属性选择更好的名称.但是,我错过了这样一个决定的背景.
我的回答是:
那么,你想要动画TextBlock
一个(自定义)窗口的内容?!
为什么要在窗口上设置样式,而不是在TextBlock
自身上?也许你应该尝试这样的事情(没试过这个!):
<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>
Run Code Online (Sandbox Code Playgroud)
的{Binding ChangeOccurred}
可能是不够的.您可能需要一个补充DataContext
到TextBlock
,或添加RelativeSource
什么的.