WPF TreeView: How to style selected items with rounded corners like in Explorer

后端 未结 3 1766
不思量自难忘°
不思量自难忘° 2020-11-28 20:17

The selected item in a WPF TreeView has a dark blue background with \"sharp\" corners. That looks a bit dated today:

3条回答
  •  [愿得一人]
    2020-11-28 20:44

    Windows 10 TreeView (and ListView) Style

    I was originally looking for a way to apply the Windows 10 color scheme to a TreeViewItem, including

    • IsMouseOver on current item only
    • Windows 10 colors which WPF already applies them to ListBox (not Windows Explorer)

    If any of you are looking for exactly this, please feel free to take the code below. I used Helge Klein's solution for the IsMouseOver issue and applied the Windows 10 colors to the XAML. Therefore I propose this as an addition to the accepted answer.

    Also, see below for a word on ListView and ComboBox as well.


    Screenshot

    App.xaml

    
    
    

    TreeViewItemHelper (by Helge Klein, minor changes / simplification)

    public static class TreeViewItemHelper
    {
        private static TreeViewItem CurrentItem;
        private static readonly RoutedEvent UpdateOverItemEvent = EventManager.RegisterRoutedEvent("UpdateOverItem", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TreeViewItemHelper));
        private static readonly DependencyPropertyKey IsMouseDirectlyOverItemKey = DependencyProperty.RegisterAttachedReadOnly("IsMouseDirectlyOverItem", typeof(bool), typeof(TreeViewItemHelper), new FrameworkPropertyMetadata(null, new CoerceValueCallback(CalculateIsMouseDirectlyOverItem)));
        public static readonly DependencyProperty IsMouseDirectlyOverItemProperty = IsMouseDirectlyOverItemKey.DependencyProperty;
    
        static TreeViewItemHelper()
        {
            EventManager.RegisterClassHandler(typeof(TreeViewItem), UIElement.MouseEnterEvent, new MouseEventHandler(OnMouseTransition), true);
            EventManager.RegisterClassHandler(typeof(TreeViewItem), UIElement.MouseLeaveEvent, new MouseEventHandler(OnMouseTransition), true);
            EventManager.RegisterClassHandler(typeof(TreeViewItem), UpdateOverItemEvent, new RoutedEventHandler(OnUpdateOverItem));
        }
        public static bool GetIsMouseDirectlyOverItem(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsMouseDirectlyOverItemProperty);
        }
        private static object CalculateIsMouseDirectlyOverItem(DependencyObject item, object value)
        {
            return item == CurrentItem;
        }
        private static void OnUpdateOverItem(object sender, RoutedEventArgs e)
        {
            CurrentItem = sender as TreeViewItem;
            CurrentItem.InvalidateProperty(IsMouseDirectlyOverItemProperty);
            e.Handled = true;
        }
        private static void OnMouseTransition(object sender, MouseEventArgs e)
        {
            lock (IsMouseDirectlyOverItemProperty)
            {
                if (CurrentItem != null)
                {
                    DependencyObject oldItem = CurrentItem;
                    CurrentItem = null;
                    oldItem.InvalidateProperty(IsMouseDirectlyOverItemProperty);
                }
    
                Mouse.DirectlyOver?.RaiseEvent(new RoutedEventArgs(UpdateOverItemEvent));
            }
        }
    }
    

    ListBox/ListView and ComboBox: In Windows 7 (and 8?), this will cause the design from TreeView to ListBox/ListView and ComboBox to differ. Therefore, if you want to apply this color scheme to these control types as well, too, use this:

    
    
    

提交回复
热议问题