我用一个
AttachedProperty
.
我用索引缓存每个触发器
TriggerCollection
. 之后
DataGridRow
被渲染,
else if (d is FrameworkElement frameworkElement)
是
true
以及
Style
以新的顺序克隆
Triggers
.
public static class TriggerAttachedBehavior
{
private static readonly Dictionary<Trigger, int> _Triggers = new Dictionary<Trigger, int>();
/// <summary>
/// Gets property value.
/// </summary>
/// <param name="attachedObj"></param>
/// <returns></returns>
public static int GetOderIndex(Trigger attachedObj)
{
return (int)attachedObj.GetValue(OderIndexProperty);
}
/// <summary>
/// Sets property value.
/// </summary>
/// <param name="attachedObj"></param>
/// <param name="value"></param>
public static void SetOderIndex(Trigger attachedObj, int value)
{
attachedObj.SetValue(OderIndexProperty, value);
}
/// <summary>
/// The <see cref="OderIndexProperty"/> DependencyProperty.
/// </summary>
public static readonly DependencyProperty OderIndexProperty = DependencyProperty.RegisterAttached("OderIndex", typeof(int), typeof(TriggerAttachedBehavior), new UIPropertyMetadata(-1, OderIndexChangedCallback));
/// <summary>
/// Occurs when OderIndexProperty has changed.
/// </summary>
/// <param name="d">Dependency object.</param>
/// <param name="args">Event arguments.</param>
private static void OderIndexChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
if (d is Trigger attachedObj)
{
_Triggers.Add(attachedObj, (int)args.NewValue);
}
else if (d is FrameworkElement frameworkElement)
{
// clone style with trigger lock
var newStyle = new Style(frameworkElement.Style.TargetType, frameworkElement.Style);
newStyle.Triggers.Clear();
// add all triggers except the base
foreach (TriggerBase triggerBase in frameworkElement.Style.Triggers)
{
if(_Triggers.Any(t => _Equals(t.Key, triggerBase)))
continue;
newStyle.Triggers.Add(triggerBase);
}
// add the base class triggers
foreach (int i in _Triggers.Values.OrderBy(t => t))
{
newStyle.Triggers.Add(_Triggers.First(t => t.Value == i).Key);
}
// apply new style
frameworkElement.Style = newStyle;
}
}
private static bool _Equals(TriggerBase x, TriggerBase y)
{
if (x.GetType() != y.GetType())
return false;
switch (x)
{
case DataTrigger dataTrigger:
return false;
case EventTrigger eventTrigger:
return false;
case MultiDataTrigger multiDataTrigger:
return false;
case MultiTrigger multiTrigger:
return false;
case Trigger trigger:
return trigger.Property.Name.Equals((y as Trigger).Property.Name);
}
return false;
}
}
<Style TargetType="DataGridRow" x:Key="DataGridRowSelectionStyle" BasedOn="{StaticResource DataGridRowDefaultStyle}">
<Setter Property="behaviors:TriggerAttachedBehavior.OderIndex" Value="0"></Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True" behaviors:TriggerAttachedBehavior.OderIndex="998">
<Setter Property="Background" Value="{extensions:Theme Key=DataGrid_Row_IsMouseOver}"/>
</Trigger>
<Trigger Property="IsSelected" Value="True" behaviors:TriggerAttachedBehavior.OderIndex="999">
<Setter Property="Background" Value="{extensions:Theme Key=DataGrid_Row_IsSelected}"/>
<Setter Property="FontWeight" Value="Bold"/>
</Trigger>
</Style.Triggers>
</Style>