NET快速开发实践中的IExtenderProvider扩展组件

简介:

     说起扩展编程组件,我们不得不起到一个接口IExtenderProvider,参考msdn的定义:定义将属性扩展到容器中的其他组件的接口;下面我贴上IExtenderProvider的定义:

    /// <summary>
    /// 定义将属性扩展到容器中的其他组件的接口。
    /// </summary>
    public interface IExtenderProvider
    {
        /// <summary>
        /// 指定此对象是否可以将其扩展程序属性提供给指定的对象。
        /// </summary>
        /// <param name="extendee">要接收扩展程序属性的System.Object。</param>
        /// <returns>如果此对象可以扩展程序属性提供给指定对象,则为true;否则为false。</returns>
        bool CanExtend(object extendee);
    }

          根据定义我们可以理解为,实现了IExtenderProvider接口的某个控件或者组件有扩展其他组件的能力,IExtenderProvider接口借助VisualStudio设计器的功能,使我们可以动态的为控件增加属性,并可以在设计时通过属性窗口修改这些属性,而不需要继承控件类。这样做的最大好处是可以借助Visual Studio的能力,并保持控件原有的设计时支持。

          IExtenderProvider接口组件提供了一种与容器中其他组件的粘合能力,这无疑是为我们提供了另一种组件的扩展思想,我理解为侵入编程,假设没有这个方式,我们扩展一个组件需求继承原有的组件并且增加一个或多个扩展属性,比如我们要达到这么一个目的,界面上指定的方本模框必须输入字符才能离开输入焦点,如果我们用传统方法,需求重写TextBox控件,代码如下:

    public class TextBoxEx:TextBox
    {
        protected override void OnDragLeave(EventArgs e)
        {
            if (this.allowInput)
            {
                if(this.Text.Trim().Length ==0)
                {
                    MessageBox.Show("文本框必须输入字符!", "提示", MessageBoxButtons.OK, 
                      MessageBoxIcon.Information);
                    if (this.CanFocus)
                        this.Focus();
                }

                base.OnDragLeave(e);
            }
        }
        
        /// <summary>
        /// 是否容器输入为空。
        /// </summary>
        [Category("验证")]
        [Description("获取/设置是否必须输入")]
        [DefaultValue(false)]
        [Browsable(true)]
        public bool AllowInput
        {
            get
            {
                return this.allowInput;
            }
            set
            {
                this.allowInput = value;
            }
        }

        /// <summary>
        /// 默认必须输入字符。
        /// </summary>
        private bool allowInput = false;
    }

          我们来在UI上拖一个TextBoxEx控件,可以通过设置属性AllowEmpty来控件是否允许输入空值:

wps_clip_image-24444[4]

          以下这种方式可以理解为.NET的原生实现方式,需求继续原来控件,并且在应用过程上需要调用UI的控件,比较麻烦,下面我们来用IExtenderProvider做一个实现:

    [ToolboxItem(true)]
    [Description("TextBox必须输入组件。")]
    [ProvideProperty("AllowInput", typeof(TextBox))]
    public partial class TextBoxAllowInput : Component, System.ComponentModel.IExtenderProvider
    {
        private Dictionary<TextBox, bool> allowInputList = null;
        public TextBoxAllowInput()
        {
            InitializeComponent();
            allowInputList = new Dictionary<TextBox, bool>();
        }

        public TextBoxAllowInput(IContainer container)
        {
            container.Add(this);
            InitializeComponent();
            allowInputList = new Dictionary<TextBox, bool>();
        }

        [Category("输入验证")]
        [Description("获取/设置文本框是否必须输入")]
        public bool GetAllowInput(TextBox textBox)
        {
            if (allowInputList.ContainsKey(textBox))
            {
                return (bool)allowInputList[textBox];
            }
            return false;
        }

        public void SetAllowInput(TextBox textBox, bool allowInput)
        {
            if (!allowInputList.ContainsKey(textBox))
            {
                allowInputList.Add(textBox, allowInput);
                textBox.Leave += new EventHandler(textBox_Leave); 
            }
            else
            {
                allowInputList[textBox] = allowInput;
            }
        }

        void textBox_Leave(object sender, EventArgs e)
        {
            TextBox tb = sender as TextBox;
            if (this.GetAllowInput(tb))
            {
                if (tb.Text.Trim().Length == 0)
                {
                    MessageBox.Show("文本框必须输入字符!", "提示", MessageBoxButtons.OK, 
                      MessageBoxIcon.Information);
                    if (tb.CanFocus)
                        tb.Focus();
                }
            }
        }        

        public bool CanExtend(object extendee)
        {
            return (extendee is TextBox); //只扩展TextBox
        }
    }

          我们来在UI上拖一个几个TextBox控件,再拖一个TextBoxAllowInput 组件,我们可以通过设置TextBox的在TextBoxAllowInput 上的扩展属性AllowEmpty来控件是否允许输入空值:

wps_clip_image-27850[4]

          上例简单的介绍了一下IExtenderProvider接口及其背后的编程思想,在开发过程中,我们可以应用这种侵入式编程接口实现很多的扩展组件如数据绑定、输入验证、焦点跳转、输入法切换等多种多样的快捷编程辅助组件。

          下面我将会介绍基于IExtenderProvider扩展技术的UI控件与实体的数据绑定组件。

QQ群:15118502

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

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

敏捷软件工程实验室


作者:魏琼东 
出处:http://www.cnblogs.com/eastjade
关于作者:有13年的软件从业经历,专注于中小软件企业软件开发过程研究,通过在技术与管理帮助中小软件企业实现技术层面开源节流的目的。熟悉需求分析、企业架构、项目管理。现主要从事基于AgileEAS.NET平台的技术咨询工作,主要服务于医疗卫生、铁路、电信、物流、物联网、制造、零售等行业。如有问题或建议,请多多赐教! 
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过mail.james@qq.com 联系我,也可以加入QQ群:113723486、199463175、116773358、116773358、212867943、147168308、59827496、193486983、15118502和大家共同讨论,非常感谢。


    本文转自魏琼东博客园博客,原文链接:http://www.cnblogs.com/eastjade/archive/2010/08/10/1796422.html,如需转载请自行联系原作者


相关文章
|
8天前
|
Linux API C#
基于 .NET 开发的多功能流媒体管理控制平台
基于 .NET 开发的多功能流媒体管理控制平台
|
8天前
|
Web App开发 前端开发 调度
一款基于 .NET + Blazor 开发的智能访客管理系统
一款基于 .NET + Blazor 开发的智能访客管理系统
|
8天前
|
前端开发 JavaScript C#
基于.NET8+Vue3开发的权限管理&个人博客系统
基于.NET8+Vue3开发的权限管理&个人博客系统
|
8天前
|
监控 前端开发 API
一款基于 .NET MVC 框架开发、功能全面的MES系统
一款基于 .NET MVC 框架开发、功能全面的MES系统
|
5月前
|
数据库
分享一个 .NET EF 6 扩展 Where 的方法
分享一个 .NET EF 6 扩展 Where 的方法
|
开发框架 程序员 API
【C#】.net core2.1,通过扩展状态代码页方法对404页面进行全局捕抓并响应信息
在开发一个网站项目时,除了异常过滤功能模块,还需要有针对404不存在的api接口和页面处理功能 本篇文章就来讲讲,如何自定义全局请求状态类来统一处理
230 0
|
SQL 存储 XML
ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法
ASP.NET Core 实战:基于 Dapper 扩展你的数据访问方法 一、前言 在非静态页面的项目开发中,必定会涉及到对于数据库的访问,最开始呢,我们使用 Ado.Net,通过编写 SQL 帮助类帮我们实现对于数据库的快速访问,后来,ORM(Object Relational Mapping,对象关系映射)出现了,我们开始使用 EF、Dapper、NHibernate,亦或是国人的 SqlSugar 代替我们原来的 SqlHelper.cs。
4284 0
|
4月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
51 7
|
4月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
86 0