2011-06-01 188 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>