当数据网格单元格的值发生变化时,我正试图在数据网格中的单元格上执行动画。
datagrid本身绑定到普通旧CLR对象的ObservableCollection。在这种情况下,假设对象是具有“名字”,“姓氏”和“年龄”属性的“人物”对象。 'Person'类实现了INotifyPropertyChanged接口,并且每个属性都在其setter中对onPropertyChanged进行了适当的调用。
这一切都很好。在datagrid定义中,我设置了我的DataTemplate来绘制每个单元格并附加了一个数据触发器......如下所示:
<DataGridTemplateColumn Header="FirstName">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Border Name="templateBorder">
<TextBlock Name="templateTextBlock" Text="{Binding Path=FirstName}" />
</Border>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=FirstName}" Value="Richard">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard AutoReverse="True">
<DoubleAnimation Storyboard.TargetName="templateTextBlock" Storyboard.TargetProperty="Opacity" To=".1" Duration="0:0:.5" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
当我的ObservableCollection中的对象更新(我更改了FirstName值)时,数据网格会更新。根据上面的例子,如果我将FirstName的值更改为'Richard',那么动画也可以正常执行。
我的问题是我需要运行我的动画,无论Firstname的新值是什么。我已经抓取了网络,但有些人似乎只能找到针对已知值触发触发器的示例,例如当FirstName是'Richard'时触发触发器,正如我在我的例子中所展示的那样。
我的问题是,无论更新属性的值如何,我如何触发数据触发器?所以基本上如何在为数据网格中的给定行更新FirstName属性时触发datatrigger。
非常感谢。
答案 0 :(得分:42)
感谢从这个问题的回答中获得的指针,我发现答案是使用EventTrigger和TargetUpdated RoutedEvent。
<DataTemplate>
<Border Name="templateBorder">
<TextBlock Name="templateTextBlock" Text="{Binding Path=FirstName, NotifyOnTargetUpdated=True}" />
</Border>
<DataTemplate.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard AutoReverse="True">
<DoubleAnimation Storyboard.TargetName="templateTextBlock" Storyboard.TargetProperty="Opacity" To=".1" Duration="0:0:.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</DataTemplate.Triggers>
</DataTemplate>
除了EventTrigger之外,唯一需要的是在设置文本块的绑定时设置'NotifyOnTargetUpdated = True'。
感谢。
答案 1 :(得分:1)
看起来你需要一个EventTrigger&#34;当事件发生时做X&#34;而不是DataTrigger。
我自己没有尝试过..但应该可以提升自定义事件FirstNameChanged并执行触发器操作以响应。
答案 2 :(得分:1)
<Storyboard x:Key="MessageStoryBoardEntry" FillBehavior="Stop">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="0:0:00.30" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:03" Value="0"/>
<EasingDoubleKeyFrame KeyTime="0:0:03.20" Value="1500"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="MessageStoryBoardExit" FillBehavior="Stop">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)">
<EasingDoubleKeyFrame KeyTime="0:0:0.001" Value="1500"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
答案 3 :(得分:0)
您可以尝试将TextBlock的DataContext设置为FirstName属性,然后使用DataContextChanged事件。
或者您可以使用PropertyChanged事件并过滤所需的属性。
无论哪种方式,我认为你将不得不使用一个事件。
答案 4 :(得分:0)
你能用价值转换器破解一下吗?
<DataTrigger Binding="{Binding Path=FirstName, Converter=FirstNameConverter}" Value="MakeItSo">
和
class FirstNameConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return "MakeItSo";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
...
}
}
我想这取决于WPF是否在每次更改属性时调用转换器,或者它是否先评估该值。我没试过,这只是一个想法...