web-dev-qa-db-ja.com

wpf-新しい値に関係なくプロパティが変更されたときにdatatriggerを起動します

データグリッドのセルの値が変化したときに、データグリッドのセルでアニメーションを実行しようとしています。

データグリッド自体は、プレーンな古い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プロパティが更新されるたびに、データトリガーを起動する方法を教えてください。

どうもありがとう。

26
Peanut

この質問への回答から得られた指針のおかげで、私は答えが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」を設定することだけでした。

ありがとう。

42
Peanut

DataTriggerの代わりに EventTrigger 「イベント発生時にXを実行する」が必要なようです。

これは自分で試したわけではありませんが、カスタムイベントFirstNameChangedを発生させて、それに応じてトリガーアクションを実行できるようにする必要があります。

1
Gishu
  <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>
1
Bathineni

TextBlockのDataContextをFirstNameプロパティに設定してから、 DataContextChanged イベントを使用することができます。

または、 PropertyChanged イベントを使用して、必要なプロパティをフィルタリングすることもできます。

どちらにしても、イベントを使用する必要があると思います。

0
Ray

値コンバーターで何かをハッキングできますか?

<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
MarcE