码迷,mamicode.com
首页 > Windows程序 > 详细

WPF 快捷键统一管理

时间:2015-05-19 12:20:40      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

    最近刚刚换了工作,到了新公司的接到第一个项目,是做一个分店零售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 快捷键统一管理

标签:

原文地址:http://www.cnblogs.com/akong/p/4513832.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!