在ContextMenu中使用ItemSource进行控制

时间:2015-11-27 15:57:38

标签: c# wpf xaml contextmenu

我试图在整个应用程序中对我的上下文菜单进行通用但动态的控制。为此,我将ContextMenu移动到Window.Resources并尝试使用之前移动它。但这还不够。 使用我当前的实现,我不能使用xaml为不同的ContextMenus使用不同的ItemSources而不需要创建另一个contextmenu模板。

所以还有一次:我可以在ListView中使用ItemSource,仍然维护模板连接。在Xaml内。我知道这可以在c#代码中使用。

<Window.Resources>
    <ContextMenu x:Key="ReadOnlyContextMenuTemplate" ItemsSource="{Binding Menu.MenuCommands}">
        <ContextMenu.ItemContainerStyle>
            <Style TargetType="MenuItem">
                <Setter Property="Header" Value="{Binding Text}"/>
                <Setter Property="Command" Value="{Binding Self}"/>
                <Setter Property="InputGestureText" Value="{Binding GestureText}"/>
                <Setter Property="Icon" Value="{Binding IconImage}">
                </Setter>
            </Style>
        </ContextMenu.ItemContainerStyle>
    </ContextMenu>
</Window.Resources>

用法

<ListView ContextMenu="{StaticResource ReadOnlyContextMenuTemplate}"/>

MenuCommands类

    public class Menu
    {
        private List<ICommand> _menuCommands;
        public List<ICommand> MenuCommands
        {
            get { return _menuCommands; }
        }

        private ICommand _commandCopy;
        public ICommand CommandCopy
        {
            get
            {
                return _commandCopy ?? (_commandCopy = new TextIconCommandHandler(
                    (parameter) => Copy(parameter), true, "Copy", "Copy.png", Key.C, ModifierKeys.Control));
            }
        }

        private ICommand _commandSelect;
        public ICommand CommandSelect
        {
            get
            {
                return _commandSelect ?? (_commandSelect = new TextIconCommandHandler(
                    (parameter) => Select(parameter), true, "Select all", "Select.png", Key.A, ModifierKeys.Control));
            }
        }

        private ICommand _commandSave;
        public ICommand CommandSave
        {
            get
            {
                return _commandSave ?? (_commandSave = new TextIconCommandHandler(
                    (parameter) => Save(parameter), true, "Save", "Save.png", Key.S, ModifierKeys.Control));
            }
        }

        public Menu()
        {
            _menuCommands = new List<ICommand>();
            var properties = this.GetType().GetProperties();
            foreach (var item in properties)
            {
                var command = item.GetValue(this, null) as ICommand;
                if(command != null)
                {
                    _menuCommands.Add(command);
                }
            }
        }
     }

TextIconCommandHandlerClass(对不起文字墙)

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace TestingTool.Commands
{
    public class CommandHandler : ICommand
    {
        private Action<object> _action;
        private bool _canExecute;
        private KeyGesture _keyGesture;
        private ICommand _self;

        public ICommand Self
        {
            get { return _self; }
            set { _self = value; }
        }

        public KeyGesture KeyGesture
        {
            get { return _keyGesture; }
            set { _keyGesture = value; }
        }

        public string GestureText
        {
            get { return _keyGesture.GetDisplayStringForCulture(CultureInfo.CurrentUICulture); }
        }

        public CommandHandler(Action<object> action, bool canExecute, Key key = Key.None, ModifierKeys keysModifier = ModifierKeys.None)
        {
            _self = this;
            _action = action;
            _canExecute = canExecute;
            _keyGesture = new KeyGesture(key, keysModifier);       
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _action(parameter);
        }
    }

    public class TextCommandHandler : CommandHandler
    {
        private string _text;

        public string Text
        {
            get { return _text; }
            set { _text = value; }
        }

        public TextCommandHandler(Action<object> action, bool canExecute, string text, Key key = Key.None, ModifierKeys keysModifier = ModifierKeys.None)
            : base(action, canExecute, key, keysModifier)
        {
            _text = text;
        }
    }

    public class TextIconCommandHandler : TextCommandHandler
    {
        private string _iconName;
        private Image _iconImage;

        public Image IconImage
        {
            get { return _iconImage; }
            set { _iconImage = value; }
        } 

        public TextIconCommandHandler(Action<object> action, bool canExecute, string text, string iconName, Key key = Key.None, ModifierKeys keysModifier = ModifierKeys.None)
            : base(action, canExecute, text, key, keysModifier)
        {
            _iconName = "Resources/" + iconName;
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.UriSource = new Uri(_iconName, UriKind.Relative);
            bi.EndInit();
            _iconImage = new Image();
            _iconImage.Source = bi;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

使用ViewModel属性的标准名称,该属性将用作ContextMenu的ItemsSource以用于各种控件。