Back

WPF 通过一个dictionary管理多个Command注册

Language 中文 English

需要开发一个族库插件,中间交互的命令很多,需要很多绑定,使用MVVM 直接绑定Command觉得整个ViewModel会过于杂乱,这里通过创建一个ICommandManage的接口管理Command。通过WPF中ValueConvert接口将传入字符串转换成ICommand命令。

c#

public interface ICommandManager
    {
        void RegisterCommand(string name, ICommand? command);
        void UnRegisterCommand(string name);
        ICommand GetCommand(string name);
    }

public class CommandManager:ICommandManager
    {
        private readonly Dictionary<string, ICommand?> _commands = new Dictionary<string, ICommand?>();
        public void RegisterCommand(string name, ICommand? command)
        {
            _commands[name] = command;
        }

        public void UnRegisterCommand(string name)
        {
            _commands.Remove(name);
        }

        public ICommand GetCommand(string name)
        {
            return _commands.TryGetValue(name, out ICommand? command) ? command : null;
        }
    }

ViewModel:

        private  ICommandManager _commandManager = new CommandManager();

        public  ICommandManager CommandManager
        {
            get => _commandManager;
            set
            {
                _commandManager = value;
                OnPropertyChanged(nameof(CommandManager));
            }
        }



_commandManager.RegisterCommand("ButtonCommand" , new MyCommand(param => { MessageBox.Show("Hello");} , para=>true));
            _commandManager.RegisterCommand("SelectedItemCommand" ,new MyCommand(GetSelectedItem ,para => true ));
            _commandManager.RegisterCommand("SkipToTargetPageCommand" , new MyCommand(SkipToTargetPage , para=>true));
            _commandManager.RegisterCommand("SkipToPreviousPageCommand", new MyCommand(SkipToPreviousPage , para=>true));
            _commandManager.RegisterCommand("SkipToNextPageCommand", new MyCommand(SkipToNextPage, para=>true));
            _commandManager.RegisterCommand("PromptFamilyCommand", new MyCommand(PromptFamily, para=>true));

Converter:

public class CommandConverter:IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is ICommandManager commandManager && parameter is string commandName)
            {
                return commandManager.GetCommand(commandName);
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

WPF

<i:Interaction.Triggers>
                                        <i:EventTrigger EventName="Click">
                                            <i:InvokeCommandAction 
                                                Command="{Binding  Path=CommandManager , ConverterParameter=ButtonCommand , Converter={StaticResource CommandConverter}  }">
                                            </i:InvokeCommandAction>
                                        </i:EventTrigger>
                                    </i:Interaction.Triggers>