в WPF - огонь datatrigger, когда изменения свойств вне зависимости от нового значения
Я пытаюсь выполнить анимацию для ячейки в datagrid, когда значение ячейки datagrid изменяется.
Сама datagrid привязана к ObservableCollection простых старых объектов CLR. В этом случае предположим, что объекты являются объектами "Person" со свойствами "Firstname", "Lastname" и "Age". Класс Person реализует интерфейс INotifyPropertyChanged, и каждое свойство имеет соответствующий вызов 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), datagrid обновляется нормально. В соответствии с приведенным выше примером, если я изменил значение FirstName на "Richard", то анимация также выполняется нормально.
Моя проблема заключается в том, что мне нужно запустить анимацию независимо от того, какое новое значение Firstname. Я ползал по сети, но ... некоторые далеко только, кажется, найти примеры запуска триггера против известного значения, например, огонь триггер, когда имя "Ричард", как я продемонстрировал в моем примере.
Мой вопрос заключается в том, как запустить datatrigger независимо от значения обновленного свойства? Итак, в основном, как я запускаю datatrigger всякий раз, когда свойство FirstName обновляется для данной строки в datagrid.
Большое спасибо.
5 ответов:
Благодаря указателям, полученным из ответов на этот вопрос, я нашел ответ, чтобы использовать 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' при настройке привязки для textblock.
Спасибо.
Похоже, что вам нужен EventTrigger "do X when an event happens" вместо DataTrigger.
Не пробовал этого сам.. но должна быть возможность вызвать ваше пользовательское событие 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>
Можно попробовать установить DataContext TextBlock в свойство 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 конвертер при каждом изменении свойства, или он сначала оценивает значение. Я не пробовал, это просто мысль...