WPF's default behavior is to change the TreeViewItem to gray when the ContextMenu opens, but like virtually everything else in WPF you can override this:
- Create an attached property ContextMenuOpened
- In the TreeViewItem Style, bind ContextMenuOpened to "ContextMenu.IsOpen"
- Add a trigger that changes the brush when ContextMenuOpened and IsSelected are both true
Here's the attached property:
public class TreeViewCustomizer : DependencyObject
{
public static bool GetContextMenuOpened(DependencyObject obj) { return (bool)obj.GetValue(ContextMenuOpenedProperty); }
public static void SetContextMenuOpened(DependencyObject obj, bool value) { obj.SetValue(ContextMenuOpenedProperty, value); }
public static readonly DependencyProperty ContextMenuOpenedProperty = DependencyProperty.RegisterAttached("ContextMenuOpened", typeof(bool), typeof(TreeViewCustomizer));
}
Here's the setter in the style:
<Setter Property="my:TreeViewCustomizer.ContextMenuOpened"
Value="{Binding ContextMenu.IsOpen, RelativeSource={RelativeSource Self}}" />
Here's the trigger:
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="my:TreeViewCustomizer.ContextMenuOpened" Value="true"/>
</MultiTrigger.Conditions>
<Setter TargetName="Bd"
Property="Background"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</MultiTrigger>
How it works: Every time the ContextMenu opens its IsOpen property is set. The binding causes your attached property to be set on the TreeViewItem. This, combined with IsSelected, invokes the trigger which changes the foreground and background colors to make the item still appear selected.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…