我有一个WPF Grid,当一个值发生变化时,我想突出显示一个单元格。这确实适用于下面的EventTrigger,但是在加载窗口时突出显示每个单元格。是否有一种“更好”的WPF方式只在设置初始值或加载窗口之后触发?
<Style TargetType="DataGridCell" x:Key="FlashStyle">
<Style.Triggers>
<EventTrigger RoutedEvent="Binding.TargetUpdated">
<BeginStoryboard>
<Storyboard x:Name="Blink" AutoReverse="True">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="00:00:01" Value="Red" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>发布于 2014-05-14 13:58:13
正如我所承诺的,我已经重新讨论了这个答案,并给出了一个例子。我发现我原来的答案无法工作,因为不可能在运行时修改触发器集合。不过,还有另一种解决办法,我将在此解释。
更新答复
由于我们无法在运行时对触发器集合进行更改,我看到了两个可能的选项:
TargetUpdated事件并忽略它。第一个选项可以通过使用TriggerBase实现。我还没试过,但这可能是个好方法。
第二种选择相当简单,并在此提供:
public class AfterLoadBehavior
{
#region TargetUpdatedAfterLoad Attached Event
public static readonly RoutedEvent TargetUpdatedAfterLoadEvent = EventManager.RegisterRoutedEvent(
"TargetUpdatedAfterLoad", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(AfterLoadBehavior));
public static void AddNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
UIElement uiElement = d as UIElement;
if (uiElement != null)
{
uiElement.AddHandler(TargetUpdatedAfterLoadEvent, handler);
}
}
public static void RemoveNeedsCleaningHandler(DependencyObject d, RoutedEventHandler handler)
{
UIElement uiElement = d as UIElement;
if (uiElement != null)
{
uiElement.RemoveHandler(TargetUpdatedAfterLoadEvent, handler);
}
}
#endregion
#region RaiseTargetUpdatedAfterLoadEvent Attached Property
public static bool GetRaiseTargetUpdatedAfterLoadEvent(FrameworkElement obj)
{
return (bool)obj.GetValue(RaiseTargetUpdatedAfterLoadEventProperty);
}
public static void SetRaiseTargetUpdatedAfterLoadEvent(FrameworkElement obj, bool value)
{
obj.SetValue(RaiseTargetUpdatedAfterLoadEventProperty, value);
}
public static readonly DependencyProperty RaiseTargetUpdatedAfterLoadEventProperty =
DependencyProperty.RegisterAttached("RaiseTargetUpdatedAfterLoadEvent", typeof(bool), typeof(AfterLoadBehavior),
new PropertyMetadata(false, OnRaiseTargetUpdatedAfterLoadEventChanged));
private static void OnRaiseTargetUpdatedAfterLoadEventChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var frameworkElement = (FrameworkElement)d;
frameworkElement.AddHandler(Binding.TargetUpdatedEvent, new RoutedEventHandler((sender, args) =>
{
if (GetIsFirstValueChange(frameworkElement))
{
SetIsFirstValueChange(frameworkElement, false);
return;
}
frameworkElement.RaiseEvent(new RoutedEventArgs(AfterLoadBehavior.TargetUpdatedAfterLoadEvent));
}));
}
#endregion
#region IsFirstValueChange Attached Property
public static bool GetIsFirstValueChange(FrameworkElement obj)
{
return (bool)obj.GetValue(IsFirstValueChangeProperty);
}
public static void SetIsFirstValueChange(FrameworkElement obj, bool value)
{
obj.SetValue(IsFirstValueChangeProperty, value);
}
public static readonly DependencyProperty IsFirstValueChangeProperty =
DependencyProperty.RegisterAttached("IsFirstValueChange", typeof(bool), typeof(AfterLoadBehavior),
new PropertyMetadata(true));
#endregion
}使用此方法,您需要修改样式如下:
<Style TargetType="DataGridCell" x:Key="FlashStyle">
<Setter Property="local:AfterLoadBehavior.RaiseTargetUpdatedAfterLoadEvent" Value="True" />
<Style.Triggers>
<EventTrigger RoutedEvent="{x:Static local:AfterLoadBehavior.TargetUpdatedAfterLoadEvent}">
<BeginStoryboard>
<Storyboard x:Name="Blink" AutoReverse="True">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)">
<EasingColorKeyFrame KeyTime="00:00:01" Value="Red" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>此行为所做的是注册到Binding.TargetUpdated事件,并在第一次调用它时忽略它。在其他情况下,它会引发新创建的TargetUpdatedAfterLoadEvent,它由您的EventTrigger处理。
因此,结果比我原先预期的要复杂一些,但是这里并没有什么疯狂的事情发生,一旦将这种行为添加到代码中,就很容易使用。希望这能有所帮助。
原来的答案(不起作用)
我不知道这是一个简单的XAML解决方案,但是您可以编写一个附加属性,它将注册到DataGridCell的Loaded事件,并且只在加载事件触发器之后添加。
https://stackoverflow.com/questions/23656577
复制相似问题