zoukankan      html  css  js  c++  java
  • .NET快速开发实践之应用IExtenderProvider实现控件焦点跳转

             我在前面的.NET快速开发实践中的IExtenderProvider扩展组件和其他两篇Post介绍了IExtenderProvider扩展编程模式和应用IExtenderProvider实现实体与对象的做法与例子,下面我为介绍一下在管理信息系统开发中一个常用的功能,控件的输入焦点跳转,我们知道,系统为我们提供了Tab和Shift+Tab切换输入焦点的功能,但是这里面有一个问题,即最终操作者最不习惯于使用Tab进行切换输入焦点,因为都已经习惯于无鼠标操作,常使用回车,上下方向键进行操作以实现焦点切换。

             那么我们如何实现这样的功能,最普通的方法是处理输入控件的KeyDown事件,判读按键是否满足跳转:例如

            private void tbName_KeyDown(object sender, KeyEventArgs e)
            {
                if(e.KeyCode == Keys.Enter) //回车向下一焦点跳转
    			{
                    this.tbInputCode1.Focus();
    			}
                else if(e.KeyCode == Keys.Up) //向上键向上一焦点跳转
    			{
                    this.tbCode.Focus();
            }

             这样的做法,我们就必须重写所有输入控件的KeyDown事件,效率低下,也影响代码的美观,我们可以通过应用应用IExtenderProvider实现另一种方式,即把这样的功能封装在一个名字叫ControlFocus的组件中:

        [ToolboxItem(true)]
        [Description("控制焦点跳转组件")]
    	[ProvideProperty( "NextControl", typeof(Control)) ]
        [ProvideProperty("PreviousControl", typeof(Control))]
    	public class ControlFocus:Component, IExtenderProvider
    	{
            Dictionary<Control, Control> _NextFocus = new Dictionary<Control, Control>();
            Dictionary<Control, Control> _PreviousFocus = new Dictionary<Control, Control>();
    
            private Keys [] nextKeys;
            private Keys[] previousKeys;
    
    		public ControlFocus()
    		{
    			
    		}
            
            public ControlFocus(System.ComponentModel.IContainer container)
            {
                container.Add(this);
            }
    
            [Category("焦点跳转")]
            [Description("获取/设置向前跳转按键集合")]
            public Keys[] NextKeys
            {
                get
                {
                    return this.nextKeys;
                }
                set
                {
                    this.nextKeys = value;
                }
            }
    
            [Category("焦点跳转")]
            [Description("获取/设置向后跳转按键集合")]
            public Keys[] PreviousKeys
            {
                get
                {
                    return this.previousKeys;
                }
                set
                {
                    this.previousKeys = value;
                }
            }
    
            [Category("焦点跳转")]
            [Description("获取/设置向前跳转控件")]
            public System.Windows.Forms.Control GetNextControl(Control control)
            {
                if (_NextFocus.ContainsKey(control))
                {
                    return _NextFocus[control];
                }
                return null;
            }
    
            public void SetNextControl(Control control, Control nextControl)
    		{
                if (_NextFocus.ContainsKey(control) != true)
    			{
    				_NextFocus.Add(control,nextControl);
                    control.KeyDown += new KeyEventHandler(Control_KeyDown);
    			}
    			else
    			{
    				_NextFocus[control] = nextControl;
    			}
    		}
    
            [Category("焦点跳转")]
            [Description("获取/设置向后跳转控件")]
            public Control GetPreviousControl(Control control)
            {
                if (_PreviousFocus.ContainsKey(control))
                {
                    return (System.Windows.Forms.Control)_PreviousFocus[control];
                }
                return null;
            }
    
            public void SetPreviousControl(Control control, Control previousControl)
    		{
                if (_PreviousFocus.ContainsKey(control) != true)
    			{
    				_PreviousFocus.Add(control,previousControl);
                    control.KeyDown += new KeyEventHandler(Control_KeyDown);
    			}
    			else
    			{
    				_PreviousFocus[control] = previousControl;
    			}
    		}        
    
    		private void Control_KeyDown(object sender, KeyEventArgs e)
    		{
    			if(NextKeysContains(e.KeyCode))
    			{
                              Control nextControl = this.GetNextControl((Control)sender);
    				if(nextControl != null && nextControl.CanFocus)
    					nextControl.Focus();
    			}
                else if (PreviousKeysContains(e.KeyCode))
    			{
                               Control previousControl = this.GetPreviousControl((Control)sender);
    				if(previousControl != null && previousControl.CanFocus)
    					previousControl.Focus();
    			}            
    		}
    
            internal bool NextKeysContains(Keys k)
            {
                if (this.nextKeys == null)
                    return false;
    
                for (int i = 0; i < this.nextKeys.Length; i++)
                {
                    if (this.nextKeys[i] == k)
                        return true;
                }
    
                return false;
            }
    
            internal bool PreviousKeysContains(Keys k)
            {
                if (this.previousKeys == null)
                    return false;
    
                for (int i = 0; i < this.previousKeys.Length; i++)
                {
                    if (this.previousKeys[i] == k)
                        return true;
                }
    
                return false;
            }
    
            #region IExtenderProvider 成员
    
            bool IExtenderProvider.CanExtend(object component)
            {
                if (component is Control && !(component is Form))
                {
                    return true;
                }
    
                return false;
            }
    
            #endregion
        }

             下面我们来看看如何应用ControlFocus,拖出一个ControlFocus设置跳转按键值,可以通过属性窗口,也可以通过代码:

            public DiagnosisEditor()
            {
                InitializeComponent();
                
                this.controlFocus1.NextKeys = new Keys[] {Keys.Enter,Keys.PageDown};
                this.controlFocus1.PreviousKeys = new Keys [] {Keys.PageUp};
            }

             下面设置输入控件的焦点跳转顺序,需要为每个控件设置下一个焦点控件和前一焦点控件:

    控件跳转

             我做了一个简单的demo,请下载Exam.DataUIMapper.rar

    QQ群:15118502

    链接:AgileEAS.NET应用开发平台介绍

    AgileEAS.NET之敏捷并行开发方法

    敏捷软件工程实验室

  • 相关阅读:
    Android创建上下文(appContext)
    java泛型——同一类型
    (转)cglib介绍与原理——CallBackFilter、延迟加载
    cglib常用api
    ES6——Proxy实现Web服务,进行方法拦截,通过方法名称生成网址
    day4幸运抽奖系统更新
    day7_abstractClass_interface
    day6_inheritance_polymorphis
    day5_package
    day4_class_method_array
  • 原文地址:https://www.cnblogs.com/eastjade/p/1801306.html
Copyright © 2011-2022 走看看