2011-06-01 192 views
19

我尝试在datagrid单元格的值发生更改时,在datagrid中的单元格上执行动画。wpf - 当数据属性更改时触发数据触发器,无论新值如何

datagrid本身绑定到一个普通的旧CLR对象的ObservableCollection。在这种情况下,可以说对象是'Person'对象,具有'Firstname','Lastname'和'Age'属性。 '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的值更改为'Richard',那么动画也会执行得很好。

我的问题是,无论Firstname的新值是什么,我都需要运行我的动画。我已经抓取了网页,但有些内容似乎只能找到触发某个已知值的例子,例如当我的例子中演示的名字是'Richard'时触发。

我的问题是我该如何触发datatrigger而不考虑更新属性的值?所以,基本上,如何在数据网格中的给定行更新FirstName属性时触发数据触发器。

非常感谢。

+0

为什么你不尝试使用视觉状态管理器...看到这篇文章。 http://stackoverflow.com/questions/15258199/blend-trigger-vs-wpf-trigger – stromms 2014-11-12 22:03:52

回答

38

由于指针从答复这个问题得到了我找到了答案是使用一个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 =真”。

谢谢。

+4

+1 - 不错的工作。我也学到了一些新东西:) – Gishu 2011-06-03 02:26:53

+0

这是做到这一点的方法,它的工作原理。我唯一的问题是EventTriggers不支持Enter和Exit操作。所以你可以做的就是启用AutoReverse来反转任何动画。 – 2016-04-07 22:23:04

+0

如果您使用“用户控件”并在后台交换ViewModels以适应正确的页面,则此方法似乎存在问题。 – 2017-08-22 20:26:45

1

它看起来像你需要一个EventTrigger“发生事件时发生X”而不是DataTrigger。

没试过此我自己..但它应该可以提高您的自定义事件FirstNameChanged和有触发行动,应对该被执行。

+0

投票指出我在正确的方向。谢谢。 – Peanut 2011-06-02 23:37:49

0

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

或者您可以使用PropertyChanged事件并筛选您想要的属性。我想你不得不使用一个事件。

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呼吁每个属性的变化转换,还是第一次评估值。我还没有尝试过,它只是一个想法...

+0

嗨马克 - 感谢您的建议。我不知道为什么,但这似乎是为数据网格中的每一行激发转换器 - 无论该行的值是否已更改。 – Peanut 2011-06-01 12:46:03

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>