首页 文章

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

提问于
浏览
22

我正在尝试在datagrid单元格的值更改时在数据网格中的单元格上执行动画 .

datagrid本身绑定到普通旧CLR对象的ObservableCollection . 在这种情况下,假设对象是具有“名字”,“姓氏”和“年龄”属性的“人物”对象 . 'Person'类实现了INotifyPropertyChanged接口,并且每个属性都在其setter中对onPropertyChanged进行了适当的调用 .

这一切都很好 . 在datagrid定义中,我设置了我的DataTemplate来绘制每个单元格并附加了一个datatrigger ......如下所示:

<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属性时触发数据触发器 .

非常感谢 .

5 回答

  • 1

    感谢从这个问题的回答中获得的指针,我发现答案是使用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' .

    谢谢 .

  • 0

    看起来你需要EventTrigger "do X when an event occurs"而不是DataTrigger .

    我自己没有尝试过..但是应该可以引发自定义事件FirstNameChanged并执行触发器操作以响应它 .

  • 41
    <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>
    
  • 0

    您可以尝试将TextBlock的DataContext设置为FirstName属性,然后使用DataContextChanged事件 .

    或者您可以使用PropertyChanged事件并过滤所需的属性 .

    无论哪种方式,我认为你将不得不使用一个事件 .

  • 1

    你能用 Value 转换器破解一下吗?

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

相关问题