在上下文菜单中进行分组

3
如果我有一系列命令,每个命令都有一个组号,那么如何在上下文菜单中呈现这些命令?
以下是我尝试过的代码,但似乎无法显示子菜单项。
namespace groupTest
{
    public class GroupedCommand
    {
        public string Name { get; set; }
        public ICommand Command { get; set; }
        public int Group { get; set; }
    }

    public partial class Window1 : Window
    {
        public List<GroupedCommand> Commands
        {
            get;
            private set;
        }

        public Window1()
        {
            Commands = new List<GroupedCommand>();
            Commands.Add(new GroupedCommand() { Name = "A", Group = 0 });
            Commands.Add(new GroupedCommand() { Name = "B", Group = 0 });
            Commands.Add(new GroupedCommand() { Name = "C", Group = 1 });
            Commands.Add(new GroupedCommand() { Name = "D", Group = 1 });

            var defView = (CollectionView)CollectionViewSource.GetDefaultView(Commands);
            defView.GroupDescriptions.Add(new PropertyGroupDescription("Group"));

            DataContext = this;
            InitializeComponent();
        }
    }
}

<Window x:Class="groupTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">

    <Window.ContextMenu>
        <ContextMenu ItemsSource="{Binding Commands}">
            <ContextMenu.GroupStyle>
                <GroupStyle>
                    <GroupStyle.ContainerStyle>
                        <Style TargetType="{x:Type GroupItem}">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="{x:Type GroupItem}">
                                        <MenuItem Header="{Binding}">
                                            <ItemsPresenter />
                                        </MenuItem>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </GroupStyle.ContainerStyle>
                </GroupStyle>
            </ContextMenu.GroupStyle>
        </ContextMenu>
    </Window.ContextMenu>
</Window>
1个回答

0

我已经通过更改GroupItem的控件模板和一个附加的行为来使其工作。

我已经替换了以下的ControlTemplate

<ControlTemplate TargetType="{x:Type GroupItem}">
    <MenuItem Header="{Binding}">
        <ItemsPresenter />
    </MenuItem>
</ControlTemplate>

使用

<ControlTemplate TargetType="{x:Type GroupItem}">
    <MenuItem Header="{Binding}" ItemsSource="{Binding Items}" Style="{StaticResource GroupMenuItemStyle}" />
</ControlTemplate>

然后,添加了一个附加的行为来在鼠标进入/离开MenuItem时显示/隐藏子菜单项

public static class GroupMenuBehavior
    {
        public static readonly DependencyProperty DummyProperty =
            DependencyProperty.RegisterAttached("Dummy", typeof (bool), typeof (GroupMenuBehavior), new PropertyMetadata(default(bool), PropertyChangedCallback));

        private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
        {
            var mi = dependencyObject as MenuItem;
            if (mi == null) return;
            if (mi.IsLoaded)
            {
                AddHandlers(mi);
            }
            else
            {
                mi.Loaded += MiOnLoaded;
            }
        }

        private static void MiOnLoaded(object sender, RoutedEventArgs routedEventArgs)
        {
            var mi = (MenuItem) sender;
            mi.Loaded -= MiOnLoaded;
            AddHandlers(mi);
        }

        static void AddHandlers(MenuItem mi)
        {
            mi.MouseEnter += MiOnMouseEnter;
            mi.MouseLeave += MiOnMouseLeave;
        }

        private static void MiOnMouseLeave(object sender, MouseEventArgs mouseEventArgs)
        {
            var mi = (MenuItem)sender;
            if (mi.IsSubmenuOpen)
                mi.IsSubmenuOpen = false;
        }

        private static void MiOnMouseEnter(object sender, MouseEventArgs mouseEventArgs)
        {
            var mi = (MenuItem) sender;
            if (mi.Items != null && mi.Items.Count != 0)
                mi.IsSubmenuOpen = true;
        }

        public static void SetDummy(MenuItem menuItem, bool value)
        {
            menuItem.SetValue(DummyProperty, value);
        }

        public static bool GetDummy(MenuItem menuItem)
        {
            return (bool) menuItem.GetValue(DummyProperty);
        }
    }

还有一个用于将上述行为附加到MenuItem的样式:

<Style TargetType="{x:Type MenuItem}" x:Key="GroupMenuItemStyle">
    <Setter Property="local:GroupMenuBehavior.Dummy" Value="True" />
</Style>

我知道,这是一个丑陋的hack/修复。但是,其他方法无法使其正常工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接