c# winform快捷键实现

2019-09-10 17:29:50 浏览数 (1)

我们在软件中经常用到快捷键,这里整理备份一下。

首先我们要定义可以作为快捷键的按键,以下是整理的 一些,自己可以根据情况来修改

代码语言:javascript复制
  public static Dictionary<int, string> HotKeys = new Dictionary<int, string>() 
        { 
            {48,"0"},  
            {49,"1"},  
            {50,"2"},      
            {51,"3"},     
            {52,"4"},    
            {53,"5"},     
            {54,"6"},    
            {55,"7"},    
            {56,"8"},    
            {57,"9"},
            {65,"A"},   
            {66,"B"},     
            {67,"C"},    
            {68,"D"},      
            {69,"E"},     
            {70,"F"},    
            {71,"G"},    
            {72,"H"},     
            {73,"I"},    
            {74,"J"},    
            {75,"K"},     
            {76,"L"},     
            {77,"M"},    
            {78,"N"},   
            {79,"O"},   
            {80,"P"},    
            {81,"Q"},     
            {82,"R"},     
            {83,"S"},      
            {84,"T"},     
            {85,"U"},     
            {86,"V"},    
            {87,"W"},     
            {88,"X"},      
            {89,"Y"},    
            {90,"Z"},        
            {112,"F1"},  
            {113,"F2"},     
            {114,"F3"},     
            {115,"F4"},    
            {116,"F5"},   
            {117,"F6"},     
            {118,"F7"},    
            {119,"F8"},     
            {120,"F9"},     
            {121,"F10"},   
            {122,"F11"},    
            {123,"F12"},
            {33,"PageUp"}, 
            {34,"PageDown"},  
            {35,"End"},      
            {36,"Home"},   
            {37,"←"},     
            {38,"↑"},   
            {39,"→"},   
            {40,"↓"},    
            {45,"Insert"},
            {46,"Delete"},
            {186,";"},   
            {187,"="},   
            {188,","},   
            {189,"-"},    
            {190,"."},    
            {191,"/"},    
            {192,"`"},   
            {219,"["},     
            {220,"\"},    
            {221,"]"}
        };

然后弄个数据表存一下定义功能对应的快捷键,表结构如下

代码语言:javascript复制
CREATE TABLE [dbo].[HotKey](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [FrmName] [nvarchar](50) NULL,
    [Sort] [int] NULL,
    [ActionName] [nvarchar](50) NULL,
    [ActionKey] [nvarchar](50) NULL,
    [KeyValue] [nvarchar](50) NULL
) ON [PRIMARY]

GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'界面' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'HotKey', @level2type=N'COLUMN',@level2name=N'FrmName'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'顺序' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'HotKey', @level2type=N'COLUMN',@level2name=N'Sort'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'功能名称' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'HotKey', @level2type=N'COLUMN',@level2name=N'ActionName'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'功能编码' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'HotKey', @level2type=N'COLUMN',@level2name=N'ActionKey'
GO

EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'热键' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'HotKey', @level2type=N'COLUMN',@level2name=N'KeyValue'
GO

系统启动的时候缓存一下设置的快捷键

代码语言:javascript复制
public static List<HotKey> HotKeySetting { get; set; }

基类窗体里面写窗体的

写KeyUP 和KeyDown事件

代码语言:javascript复制
 bool m_blnCtrl = false;
 bool m_blnAlt = false;
 bool m_blnShift = false;

        [Description("定义的热键列表"), Category("自定义")]
        public Dictionary<int, string> HotKeys { get; set; }
        //如果事件返回true则表示已经找到了快捷键事件,则不再向下传递
        public delegate bool HotKeyEventHandler(string strHotKey);
        /// <summary>
        /// 热键事件
        /// </summary>
        [Description("热键事件"), Category("自定义")]
        public event HotKeyEventHandler HotKeyDown;


 protected void FrmBase_KeyUp(object sender, KeyEventArgs e)
        {
            if (HotKeyDown != null && HotKeys != null)
            {
                if (e.KeyCode == Keys.Control || e.KeyCode == Keys.ControlKey)
                    m_blnCtrl = false;
                if (e.KeyCode == Keys.Alt || e.KeyCode == Keys.Menu)
                    m_blnAlt = false;
                if (e.KeyCode == Keys.Shift || e.KeyCode == Keys.ShiftKey)
                    m_blnShift = false;
            }
        }

        protected void FrmBase_KeyDown(object sender, KeyEventArgs e)
        {
            if (HotKeyDown != null && HotKeys != null)
            {
                if (e.KeyCode == Keys.Control || e.KeyCode == Keys.ControlKey)
                    m_blnCtrl = true;
                if (e.KeyCode == Keys.Alt || e.KeyCode == Keys.Menu)
                    m_blnAlt = true;
                if (e.KeyCode == Keys.Shift || e.KeyCode == Keys.ShiftKey)
                    m_blnShift = true;
                if (HotKeys.ContainsKey(e.KeyValue))
                {
                    string strKey = string.Empty;
                    if (m_blnCtrl)
                    {
                        strKey  = "Ctrl ";
                    }
                    if (m_blnAlt)
                    {
                        strKey  = "Alt ";
                    }
                    if (m_blnShift)
                    {
                        strKey  = "Shift ";
                    }
                    strKey  = HotKeys[e.KeyValue];

                    if (HotKeyDown(strKey))
                    {
                        e.Handled = true;
                        e.SuppressKeyPress = true;
                    }
                }
            }
        }            

你会注意到keyup和kedown事件的修饰符是protected,为什么要用protected呢?是因为窗体的一些输入控件的按键事件是不会传递到窗体的,比如textbox这些,所有需要手动指定一下

子窗体中注册事件就可以了,如果你没有用基类窗体,那么直接写在一起就可以了

代码语言:javascript复制
this.HotKeys = HotKeys;
            this.HotKeyDown  = FrmMain_HotKeyDown;
            //将输入框的2个事件指向窗体的2个事件
            this.txtSearch.KeyDown  = this.FrmBase_KeyDown;
            this.txtSearch.KeyUp  = this.FrmBase_KeyUp;

/// <summary>
        /// 热键按下事件
        /// </summary>
        /// <param name="strHotKey">热键值</param>
        /// <returns>当返回true则表示不再向下传递按键事件,通常当匹配到热键操作后返回true</returns>
        bool FrmMain_HotKeyDown(string strHotKey)
        {
            Console.WriteLine(strHotKey);
            string strHotAction = GetHotKeyAction("FrmMain", strHotKey);
            if (string.IsNullOrEmpty(strHotAction))
                return false;
            else
            {
                //这里根据返回的功能名称做操作就可以了
                return true;
            }
        }


public static string GetHotKeyAction(string strFrom, string strHotKey)
        {
            var entity = HotKeySetting.Find(p => p.FrmName.ToLower() == strFrom.ToLower() && p.KeyValue.ToStringExt().ToLower() == strHotKey.ToLower());
            if (entity != null)
                return entity.ActionKey;
            else
                return string.Empty;
        }

这样就可以了

0 人点赞