wpf - запускает триггер данных при изменении свойства независимо от нового значения

Я пытаюсь выполнить анимацию для ячейки в сетке данных, когда значение ячейки сетки данных изменяется.

Сам datagrid привязан к ObservableCollection из простых старых объектов CLR. В этом случае допустим, что объекты являются объектами «Человек» со свойствами «Имя», «Фамилия» и «Возраст». Класс Person реализует интерфейс INotifyPropertyChanged, и каждое свойство имеет соответствующий вызов onPropertyChanged в его установщике.

Все в порядке. В определении datagrid я установил 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 на «Ричард», анимация тоже будет выполнена нормально.

Моя проблема в том, что мне нужно запускать анимацию независимо от нового значения имени. Я просматривал Интернет, но некоторые, кажется, находят только примеры срабатывания триггера против известного значения, например. активируйте триггер, когда FirstName - «Ричард», как я продемонстрировал в моем примере.

У меня вопрос: как запустить триггер данных независимо от значения обновленного свойства? Итак, в основном, как мне запускать триггер данных всякий раз, когда свойство FirstName обновляется для данной строки в сетке данных.

Большое спасибо.


person Peanut    schedule 01.06.2011    source источник
comment
Почему бы вам не попробовать использовать Visual State Manager ... См. Этот пост. stackoverflow.com/questions/15258199/   -  person stromms    schedule 13.11.2014


Ответы (4)


Благодаря указателям, полученным в ответах на этот вопрос, я обнаружил, что ответ заключался в использовании 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» при настройке привязки для текстового блока.

Спасибо.

person Peanut    schedule 02.06.2011
comment
Это способ сделать это, и он работает. Единственная проблема, с которой я столкнулся, это то, что EventTrigger не поддерживает действия Enter и Exit. Итак, все, что вы можете сделать, это включить AutoReverse, чтобы отменить любую анимацию. - person Matt Becker; 08.04.2016
comment
Похоже, что с этим методом возникает проблема, если вы используете пользовательские элементы управления и обмениваетесь моделями представления в фоновом режиме, чтобы они соответствовали правильной странице. - person Samir Banjanovic; 22.08.2017

Похоже, вам нужен EventTrigger "do X, когда событие происходит "вместо DataTrigger.

Сам не пробовал ... но должно быть возможно вызвать ваше настраиваемое событие FirstNameChanged и выполнить триггерные действия в ответ на это.

person Gishu    schedule 01.06.2011

Вы можете попробовать установить DataContext TextBlock на свойство FirstName, а затем использовать DataContextChanged.

Или вы можете использовать событие и фильтр PropertyChanged за недвижимость, которую вы хотите.

В любом случае, я думаю, вам придется использовать событие.

person Ray    schedule 01.06.2011

Не могли бы вы что-нибудь взломать с помощью преобразователя значений?

<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 преобразователь при каждом изменении свойства или сначала оценивает значение. Не пробовала, просто мысль ...

person MarcE    schedule 01.06.2011
comment
Привет, Марк - спасибо за предложение. Я не уверен, почему, но это, похоже, запускает преобразователь для каждой строки в сетке данных - независимо от того, изменилось ли значение для этой строки или нет. - person Peanut; 01.06.2011