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>
4

1 に答える 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>

私は知っています、それは醜いハック/修正です。しかし、他の方法では機能しませんでした。

于 2013-10-29T22:57:27.123 に答える