データグリッドのセルの値が変化したときに、データグリッドのセルでアニメーションを実行しようとしています。
データグリッド自体は、プレーンな古いCLRオブジェクトのObservableCollectionにバインドされています。この場合、オブジェクトが、「Firstname」、「Lastname」、および「Age」のプロパティを持つ「Person」オブジェクトであるとしましょう。 'Person'クラスはINotifyPropertyChangedインターフェイスを実装し、各プロパティはそのセッターでonPropertyChangedへの適切な呼び出しを持っています。
これで結構です。データグリッドの定義では、各セルを描画するための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の新しい値に関係なく、アニメーションを実行する必要があることです。私はWebをクロールしましたが、既知の値に対してトリガーを起動する例を見つけるだけのようです。私の例で示したように、FirstNameが 'Richard'のときにトリガーを起動します。
私の質問は、更新されたプロパティの値に関係なく、どのようにしてデータトリガーを起動するかです。したがって、基本的には、データグリッドの特定の行のFirstNameプロパティが更新されるたびに、データトリガーを起動する方法を教えてください。
どうもありがとう。
この質問への回答から得られた指針のおかげで、私は答えが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」を設定することだけでした。
ありがとう。
DataTriggerの代わりに EventTrigger 「イベント発生時にXを実行する」が必要なようです。
これは自分で試したわけではありませんが、カスタムイベントFirstNameChangedを発生させて、それに応じてトリガーアクションを実行できるようにする必要があります。
<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>
TextBlockのDataContextをFirstNameプロパティに設定してから、 DataContextChanged イベントを使用することができます。
または、 PropertyChanged イベントを使用して、必要なプロパティをフィルタリングすることもできます。
どちらにしても、イベントを使用する必要があると思います。
値コンバーターで何かをハッキングできますか?
<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がコンバーターを呼び出すか、それとも最初に値を評価するかによって異なります。私は試したことはありません、それはただの考えです...