wpf - 无论新值如何,属性更改时触发datatrigger

时间:2011-06-01 08:07:02

标签: wpf datagrid datatrigger

当数据网格单元格的值发生变化时,我正试图在数据网格中的单元格上执行动画。

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。

非常感谢。

5 个答案:

答案 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是否在每次更改属性时调用转换器,或者它是否先评估该值。我没试过,这只是一个想法...