.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群:120661978,125643764


本文转自 agilelab 51CTO博客,原文链接:http://blog.51cto.com/agilelab/561931

相关文章
|
1月前
|
SQL 开发框架 数据可视化
企业应用开发中.NET EF常用哪种模式?
企业应用开发中.NET EF常用哪种模式?
|
2月前
|
开发框架 JavaScript 前端开发
5个.NET开源且强大的快速开发框架(帮助你提高生产效率)
5个.NET开源且强大的快速开发框架(帮助你提高生产效率)
|
1天前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
|
27天前
|
数据安全/隐私保护 Windows
.net三层架构开发步骤
.net三层架构开发步骤
7 0
|
27天前
深入.net平台的分层开发
深入.net平台的分层开发
40 0
|
2月前
|
开发框架 前端开发 .NET
福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!
为了便于大家查找,特将之前开发的.Net Core相关的五大案例整理成文,共计440页,32w字,免费提供给大家,文章底部有PDF下载链接。
32 1
福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!
|
2月前
|
SQL 开发框架 前端开发
ASP.NET WEB项目中GridView与Repeater数据绑定控件的用法
ASP.NET WEB项目中GridView与Repeater数据绑定控件的用法
31 0
|
3月前
|
C#
.NET开发中合理使用对象映射库,简化和提高工作效率
.NET开发中合理使用对象映射库,简化和提高工作效率
|
3月前
|
开发框架 前端开发 JavaScript
一款基于.NET Core的快速开发框架、支持多种前端UI、内置代码生成器
一款基于.NET Core的快速开发框架、支持多种前端UI、内置代码生成器
|
3月前
|
开发框架 前端开发 .NET
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
ASP.NET CORE 3.1 MVC“指定的网络名不再可用\企图在不存在的网络连接上进行操作”的问题解决过程
38 0