WPF 快捷键统一管理

    最近刚刚换了工作,到了新公司的接到第一个项目,是做一个分店零售POS系统。客户对界面要求比较高,所以采用了WPF做为客户端开发技术。在POS系统中,快捷键是比较重要的功能,有很多快捷键在功能是实现上相似,WPF需要在每个页面上配置InputBindings。为了维护、开发便利,对快捷键做统一管理,变得很有必要。现在我来介绍一下实现。

   要做到统一管理,我的想法就是让快捷键变成可配置的,其次,能根据配置自动绑定快捷键及处理句柄。废话不多说直接上代码。

 

1、KeyboardShortcuts 快捷键统一管理的入口

  public class KeyboardShortcuts

    {

        private const string COFINGFILE = "KeyboardShortcutsRule.Config";

        public KeyboardShortcuts()

        {

            Rules = new List<KeyboardShortcutsRule>();

            LoadConfig();

        }



        public List<KeyboardShortcutsRule> Rules { get; set; }



        public void ActiveKeysBindings(Window window)

        {

            foreach (var item in Rules)

            {

                if (!item.IgnoreWindow.Contains(window.GetType()))

                {

                    if (item.Effectivity.Count == 0 || item.Effectivity.Contains(window.GetType()))

                    {

                        window.InputBindings.Add(new InputBinding(item.Command.GetCommand(), new KeyGestureConverter().ConvertFromString(item.Keys) as KeyGesture)

                                {

                                    CommandParameter = window

                                });

                    }

                }

            }

        }



        private static KeyboardShortcuts current = null;

        public static KeyboardShortcuts Current

        {

            get

            {

                if (current == null)

                {

                    current = new KeyboardShortcuts();

                }

                return current;

            }



        }



        public void LoadConfig()

        {

            try

            {

                XDocument doc = XDocument.Load(COFINGFILE);

                this.Rules = doc.Element("Settings").Elements("KeyboardShortcuts")

                    .Select(o =>

                        new KeyboardShortcutsRule()

                        {

                            Name = o.Attribute("Name").Value,



                            IsShowInHelp = o.Attribute("IsShowInHelp") != null ? Convert.ToBoolean(o.Attribute("IsShowInHelp").Value) : true,



                            Keys = o.Attribute("Keys").Value,



                            IgnoreWindow = new List<Type>().InitListType(o.Elements("Ignore")),



                            Effectivity = new List<Type>().InitListType(o.Elements("Effect")),



                            Command = o.Attribute("Command").Value.InitCommand()



                        }

                        ).ToList();



            }

            catch { }

        }



        public void SaveConfig()

        {

            try

            {

                XDocument doc = new XDocument();

                var element = new XElement("Settings");

                foreach (var item in Rules)

                {

                    var cmdType = item.Command.GetType();

                    XElement node = new XElement(

                        "KeyboardShortcuts",

                        new XAttribute("Name", item.Name),

                        new XAttribute("Keys", item.Keys),

                        new XAttribute("IsShowInHelp", item.IsShowInHelp),

                        new XAttribute("Command", string.Format("{0}|{1}", cmdType.Assembly.FullName, cmdType.ToString())));



                    foreach (var childItem in item.IgnoreWindow)

                    {

                        XElement ignoreList = new XElement("Ignore", childItem);

                        node.Add(ignoreList);

                    }

                    foreach (var childItem in item.Effectivity)

                    {

                        XElement effectList = new XElement("Effect", childItem);

                        node.Add(effectList);

                    }

                    element.Add(node);

                }

                doc.Add(element);

                doc.Save(COFINGFILE);



            }

            catch { }

        }





    }

 

2、快捷键配置规则实体

    public class KeyboardShortcutsRule

    {

        public KeyboardShortcutsRule()

        {

            IsShowInHelp = true;

        }



        public string Name { get; set; }



        public string Keys { get; set; }



        public bool IsShowInHelp { get; set; }



        public List<Type> IgnoreWindow { get; set; }



        public List<Type> Effectivity { get; set; }





        public IKeyboardShortcutsCommand Command { get; set; }

    }

 

3、对XML TO LINQ的扩展

public static class LinqExtensions

    {

        public static List<Type> InitListType(this List<Type> _this, IEnumerable<XElement> ignoreNodes)

        {

            if (_this == null)

                _this = new List<Type>();

            foreach (var item in ignoreNodes)

            {

                _this.Add(Assembly.GetExecutingAssembly().GetType(item.Value));

            }

            return _this;

        }



        public static IKeyboardShortcutsCommand InitCommand(this string _this)

        {

            var results = _this.Split("|".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);



            if (results.Count() == 2)

            {

                return Assembly.Load(results[0]).CreateInstance(results[1]) as IKeyboardShortcutsCommand;

            }

            else

            {

                return Assembly.GetExecutingAssembly().CreateInstance(results[0]) as IKeyboardShortcutsCommand;

            }

        }

    }

 

 

 

4、快捷键处理命令接口【实现这个接口的对象,在绑定快捷键后将被自动激发,PosCommand实现了WPF的ICommand接口】

    public interface IKeyboardShortcutsCommand

    {

        PosCommand GetCommand();

        string Describe { get; set; }

    }

 

5、PosCommand实现了WPF的ICommand接口

public class PosCommand : ICommand

    {

        public PosCommand() { }

        public PosCommand(Action func)

        {

            Processor = func;

        }



        public PosCommand(Action func, string describe)

        {

            Processor = func;

            Describe = describe;

        }

        public PosCommand(Action<object> func, string describe)

        {

            ProcessorForParameter = func;

            Describe = describe;

        }



        public string Describe { get; set; }



        public Action Processor { get; set; }



        public Action<object> ProcessorForParameter { get; set; }



        public bool CanExecute(object parameter)

        {

            if (Processor != null)

                return true;

            if (ProcessorForParameter != null)

            {

                return true;

            }

            return false;

        }





        public void Execute(object parameter)

        {

            if (Processor != null)

                Processor();

            if (ProcessorForParameter != null)

                ProcessorForParameter(parameter);

        }





        public event EventHandler CanExecuteChanged;

    }

 

6、实现快捷键绑定命令

    public class HelpCommand : IKeyboardShortcutsCommand

    {

        public HelpCommand()

        {

            Describe = "帮助";

        }



        public PosCommand GetCommand()

        {

            return new PosCommand((o) =>

            {

                Help page = new Help();

                page.Show();

            }, Describe);

        }





        public string Describe { get; set; }

    }

 

7、配置

<?xml version="1.0" encoding="utf-8"?>

<Settings>

  <KeyboardShortcuts Name="Help" Keys="F1" IsShowInHelp="true" Command="Pharos.POS.Retailing.HelpCommand">

    <Ignore>Pharos.POS.Retailing.Login</Ignore>

  </KeyboardShortcuts>

  <KeyboardShortcuts Name="ExitSystem" Keys="Alt+F4"  Command="Pharos.POS.Retailing.ExitSystemCommand">

    <Effect>Pharos.POS.Retailing.MainWindow</Effect>

    <Effect>Pharos.POS.Retailing.Login</Effect>

  </KeyboardShortcuts>

    <KeyboardShortcuts Name="LockScreen" Keys="Ctrl+D" Command="Pharos.POS.Retailing.LockScreenCommand">

    <Effect>Pharos.POS.Retailing.MainWindow</Effect>

  </KeyboardShortcuts>

  <KeyboardShortcuts Name="Cannel" Keys="Escape" Command="Pharos.POS.Retailing.CannelCommand"></KeyboardShortcuts>

</Settings>

 

8、引用,并启用快捷键设置

    public static class WindowExtensions

    {

        public static void InitPublicSettings(this Window _this)

        {

            //激活快捷键

            KeyboardShortcuts.Current.ActiveKeysBindings(_this);

        }

  }
    public partial class Login : Window

    {

        public Login()

        {

            InitializeComponent();

            this.InitPublicSettings();



        }  

   }

 

总结,这么做的好处就是让快捷键自定义变得很容易,只需要实现IKeyboardShortcutsCommand,配置规则文档。但是也带来了安全性问题,任何人只要稍微了解这里的机制,就可以利用快捷键的反射机制,注入程序木马等等问题,就算不懂电脑编程的,删除该配置文件也会造成快捷键失效等等问题。

 

你可能感兴趣的:(WPF)