C# 的WPF事件触发器
我有一个WPFC# 的WPF事件触发器,c#,wpf,xaml,triggers,eventtrigger,C#,Wpf,Xaml,Triggers,Eventtrigger,我有一个WPF网格,我想在值更改时突出显示一个单元格。这确实适用于下面的EventTrigger,但在加载窗口时会高亮显示每个单元格。是否有一种“更好”的WPF方法仅在设置初始值或加载窗口后触发 <Style TargetType="DataGridCell" x:Key="FlashStyle"> <Style.Triggers> <EventTrigger RoutedEvent="Binding.TargetUpdated">
网格
,我想在值更改时突出显示一个单元格。这确实适用于下面的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>
正如我承诺的那样,我重新审视了这个答案,并给出了一个例子。我发现我的原始答案无法工作,因为无法在运行时修改触发器集合。还有另一个解决方案,我将在这里解释 最新答案 由于我们无法在运行时更改触发器集合,因此我看到了两个可能的选项:
TargetUpdated
事件并忽略它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
事件,并在第一次调用它时忽略它。对于其他时间,它会引发新创建的targetUpdateAfterLoadEvent
,该事件由EventTrigger
处理
所以它比我最初预期的要复杂一些,但是这里没有什么疯狂的事情发生,一旦你把这个行为添加到你的代码中,它就很容易使用了。
希望这有帮助
原始答案(无效)
我不知道有什么简单的XAML专用解决方案可以解决这个问题,但您可以编写一个附加属性,它将注册到DataGridCell的
Loaded
事件,并且只在事件触发器加载后添加它。这听起来不必要复杂,我希望有一个优雅的解决方案:)代码方面,这是一个非常简单的解决方案,可以在5分钟内编码。稍后我会尝试用一个例子更新我的答案。非常好,没有我想的那么复杂!谢谢你的邀请,阿迪