玩转控件:封装Dev的LabelControl和TextEdit

缘由

        俗话说的好:"工欲善其事必先利其器",作为软件攻城狮也是同样道理,攻城狮开发的软件目的是简化客户的操作,让客户动动手指就可以完成很多事情,减少人力成本。这也是系统/软件存在的目的。那对于攻城狮来说怎么简化自己的操作?让自己也动动手指就可以减少很多重复的工作呢?如果你对此也有同样的疑问或兴趣,那就跟作者一起看下去吧!

        说到利器,自然而然的会想到宇宙第一IDE——Visual Studio 随着版本的迭代,大大的加快了攻城狮的编码效率。那对于我们自己开发的软件,如何减少重复操作,加快软件进度呢?这就是作者今日的主题——封装控件。

        作者几年前有幸作为公司代表,到金蝶总部参观,并学习当年金蝶最新科技——K3 Cloud,说实话,作者当年年轻气盛,和普遍技术开发一样,心高气傲,对除自己研发以外的软件不屑一顾,觉得自己才是最流P的!现在好了,善恶终有报,轮到自己爬着学习K3 Cloud的控件封装来造轮子了...

        想当年,金戈铁马,气吞万里如虎!....现如今,想起来都是泪...

        扯远了,还是回到本篇的主题造轮子...哦,不!玩转控件!封装自己的插件吧!

        今天作者主要介绍的是,封装Dev的LabelControl和TextEdit。原因很简单,说的好听就是简化自己重复操作,封装前,拖控件大法,先拖一个LabelControl ,完善它的属性。在拖一个TextEdit,完善它的属性,必要时还要完善它的控件。你以为现在就完了吗?不对,还要拖动一下,看看上下左右的对齐效果....emmmmm~

实现

        Talk is Cheap,Show me the Code!

        首先我们先新建一个用户控件,继承UserControl,为了减少冗余代码,作者把命名为BaseControl,后续所有用户控件全部继承此类。

 public partial class KzxBaseControl : System.Windows.Forms.UserControl,IControl

        其中IControl接口主要用来声明,控件的一些属性和事件,部分代码如下(代码篇幅较长,有需要公众号call我,源码免费赠送):

    /// <summary>/// 控件事件委托/// </summary>/// <param name="sender">事件发起者</param>/// <param name="e">事件参数</param>public delegate void KzxControlOperateEventHandler(object sender, ControlEventArgs e);/// <summary>/// 获取多语言文本事件委托/// </summary>/// <param name="sender">事件发起者</param>/// <param name="messageCode">语言标识</param>/// <param name="text">多语言的文本</param>public delegate void KzxGetLanguageEventHandler(object sender, string messageCode, ref string text);public interface IControl{/// <summary>/// 有Load方法/// </summary>bool HasLoad { get; }/// <summary>/// 被引用后允许修改/// true允许,false不允许/// </summary>bool AllowEdit { get; set; }/// <summary>/// 多语言环境下显示文本的对应标识/// </summary>string MessageCode { get; set; }/// <summary>/// 设计时的显示,方便设计员工识别/// </summary>string DesigeCaption { get; set; }/// <summary>/// 控件的唯一标识/// </summary>string Key { get; set; }/// <summary>/// True控件可用,False控件不可用/// </summary>Boolean Enabled { get; set; }/// <summary>/// True控件可见,False控件不可见/// </summary>Boolean Visible { get; set; }/// <summary>/// Tag标志,用于存储任何数据/// </summary>object Tag { get; set; }/// <summary>/// 设计时的可用性/// </summary>Boolean DesigeEnabled { get; set; }......

        用户控件父类,主要集中所有用户控件的通用属性、方法和事件,部分代码如下:

 private bool _AllowEdit = true;/// <summary>/// 被引用后允许修改/// true允许,false不允许/// </summary>[Category("验证"), Description("AllowEdit,被引用后允许修改,true允许,false不允许"), Browsable(true)][McDisplayName("AllowEdit")]public virtual bool AllowEdit{get{return this._AllowEdit;}set{this._AllowEdit = value;}}private string _MessageCode = "0";/// <summary>/// 多语言环境下显示文本的对应标识/// </summary>[Category("多语言"), Description("MessageCode,多语言环境下显示文本的对应标识"), Browsable(true)][McDisplayName("MessageCode")]public virtual string MessageCode{get{return this._MessageCode;}set{this._MessageCode = value;}}private string _DesigeCaption = "显示标题";/// <summary>/// 没有多语言的情况下的默认显示标题/// </summary>[Category("多语言"), Description("DesigeCaption,没有多语言的情况下的默认显示标题"), Browsable(true)][McDisplayName("DesigeCaption")]public virtual string DesigeCaption{get{return this._DesigeCaption;}set{this._DesigeCaption = value;}}private string _Key = string.Empty;/// <summary>/// 控件的唯一标识/// </summary>[Category("数据"), Description("Key,控件的唯一标识"), Browsable(true)][McDisplayName("Key")]public virtual string Key{get{if (string.IsNullOrWhiteSpace(this._Key) == true){if (string.IsNullOrWhiteSpace(this.Table) == false && string.IsNullOrWhiteSpace(this.Field) == false){this._Key = this.Table + "." + this.Field;}else if (string.IsNullOrWhiteSpace(this.Table) == false){this._Key = this.Table;}} if (string.IsNullOrEmpty(this._Key)) return this.Name; return this._Key;}set{this._Key = value;}}private bool _DesigeEnabled = true;/// <summary>/// 设计时的可用性/// </summary>[Category("特性"), Description("DesigeEnabled,设计时的可用性"), Browsable(true)][McDisplayName("DesigeEnabled")]public virtual bool DesigeEnabled{get{return this._DesigeEnabled;}set{this._DesigeEnabled = value;//this.Enabled = value;}}private bool _DesigeVisible = true;/// <summary>/// 设计时可见性/// </summary>[Category("特性"), Description("DesigeVisible,设计时可见性"), Browsable(true)][McDisplayName("DesigeVisible")]public virtual bool DesigeVisible{get{return this._DesigeVisible;}set{this._DesigeVisible = value;//this.Visible = value;if (this.DesignMode == true){if (value == false){this.BorderStyle = BorderStyle.Fixed3D;}else{this.BorderStyle = BorderStyle.None;}}else{//this.Visible = value;}}}
 /// <summary>
/// 触发控件事件
/// </summary>
/// <param name="sender">事件发起者</param>
/// <param name="eventName">事件名称</param>
/// <param name="e">事件参数</param>
protected virtual void RaiseEvent(object sender, string eventName, object e)
{ControlEventArgs args = new ControlEventArgs();args.CurrentControl = sender;args.EventId = eventName;args.SystemEventArgs = e;args.FieldName = this.Field;args.TableName = this.Table;args.Key = this.Key;if (this.KzxControlOperate != null){this.KzxControlOperate(this, args);e = args.SystemEventArgs;}
}private static MethodInfo _methodInfo = null;/// <summary>
/// 获取多语言文本
/// </summary>
/// <param name="messageCode">语言文本标识</param>
/// <param name="defaultMessage">默认的文本</param>
/// <returns>取到的文本</returns>
protected virtual string GetLanguage(string messageCode, string defaultMessage)
{string text = string.Empty;try{text = defaultMessage;string filepath = System.IO.Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "KzxCommon.dll");Assembly assembly = null;object obj = null;Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();for (int i = 0; i < assemblies.Length; i++){if (assemblies[i].GetName().Name.Equals("KzxCommon", StringComparison.OrdinalIgnoreCase) == true){assembly = assemblies[i];break;}}if (assembly == null){assembly = Assembly.LoadFrom(filepath);}obj = assembly.CreateInstance("KzxCommon.sysClass");text = defaultMessage;if (_methodInfo == null){if (obj != null){_methodInfo = obj.GetType().GetMethod("ssLoadMsg", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);if (_methodInfo != null){text = _methodInfo.Invoke(obj, new object[] { messageCode }).ToString();}}}else{text = _methodInfo.Invoke(obj, new object[] { messageCode }).ToString();}}catch (Exception ex){}return string.IsNullOrWhiteSpace(text) == true ? defaultMessage : text;
}protected virtual void OnKzxBaseControlLoad()
{object obj = null;PropertyInfo pi = null;for (int i = 0; i < this.Controls.Count; i++){if (this.Controls[i].Name.Equals("ValueControl", StringComparison.OrdinalIgnoreCase) == true){pi = this.Controls[i].GetType().GetProperty("ErrorIconAlignment");if (pi != null){pi.SetValue(this.Controls[i], ErrorIconAlignment.TopRight, null);}}}
}protected override void OnControlAdded(System.Windows.Forms.ControlEventArgs e)
{base.OnControlAdded(e);OnKzxBaseControlLoad();SetAppearance();
}

        介绍完基类,我们新建在新建要给用户控件来继承它,并实现业务需求:

    /// <summary>/// 文本框验证/// </summary>[ToolboxBitmapAttribute(typeof(Bitmap), "文本框")]public partial class KzxTextBox : KzxBaseControl

        布局方面,应自己要求,气运丹田,使出拖控件大法!

        此处无需做任何属性、事件设置。只需把我们日常常用到的属性、事件,用特性标记起来即可。部分代码如下:

 private DevExpress.XtraEditors.Controls.BorderStyles _BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.Default;
/// <summary>
/// 边框显示格式
/// </summary>
[Category("数据格式"), Description("KzxBorderStyle,边框显示格式"), Browsable(true)]
[McDisplayName("KzxBorderStyle")]
public override DevExpress.XtraEditors.Controls.BorderStyles KzxBorderStyle
{get{return this.ValueControl.Properties.BorderStyle;}set{this._BorderStyle = value;this.ValueControl.Properties.BorderStyle = value;}
}/// <summary>
/// 没有多语言的情况下的默认显示标题
/// </summary>
[Category("多语言"), Description("DesigeCaption,没有多语言的情况下的默认显示标题"), Browsable(true)]
[McDisplayName("DesigeCaption")]
public override string DesigeCaption
{get{return this.CaptionControl.Text.Trim();}set{this.CaptionControl.Text = value;}
}private bool _IsNull = true;
/// <summary>
/// 可空性
/// </summary>
[Category("验证"), Description("IsNull,可空性"), Browsable(true)]
[McDisplayName("IsNull")]
public override bool IsNull
{get{SetBackColor();return this._IsNull;}set{this._IsNull = value;SetBackColor();}
}/// <summary>
/// 只读性
/// </summary>
[Category("验证"), Description("ReadOnly,只读性"), Browsable(true)]
[McDisplayName("ReadOnly")]
public override bool ReadOnly
{get{SetBackColor();return this.ValueControl.Properties.ReadOnly;}set{this.ValueControl.Properties.ReadOnly = value;SetBackColor();if (value == false){this.ValueControl.BackColor = Color.White;}}
}private int maxLength = 0;
/// <summary>
/// 可录入的最大长度
/// </summary>
[Category("验证"), Description("MaxLength,可录入的最大长度"), Browsable(true)]
[McDisplayName("MaxLength")]
public override int MaxLength
{get{return maxLength;}set{maxLength = value;}
}private Int32 _CaptionLabelWidth = 75;
/// <summary>
/// 显示标题宽度
/// </summary>
[Category("外观"), Description("CaptionLabelWidth,显示标题宽度"), Browsable(true)]
[McDisplayName("CaptionLabelWidth")]
public Int32 CaptionLabelWidth
{get{return this.CaptionControl.Width;}set{this._CaptionLabelWidth = value;this.CaptionControl.Width = value;}
}private string toolTipMaxLengthText = string.Empty;
/// <summary>
/// 数据长度不能超过数据库长度提示文本  
/// </summary>
public override string ToolTipMaxLengthText
{get { return toolTipMaxLengthText; }set { toolTipMaxLengthText = value; }
}/// <summary>
/// 提示信息
/// </summary>
[Category("汽泡提示"), Description("ToolTipText,提示信息"), Browsable(true)]
[McDisplayName("ToolTipText")]
public override string ToolTipText
{get{return (ValueControl == null) == true ? string.Empty : ValueControl.ToolTip;}set{if (ValueControl != null){ValueControl.ToolTip = value;}if (CaptionControl != null){CaptionControl.ToolTip = value;}}
}private string _ToolTipMessageCode = string.Empty;
/// <summary>
/// 提示多语言标识
/// </summary>
[Category("汽泡提示"), Description("ToolTipMessageCode,提示信息多语言标识"), Browsable(true)]
[McDisplayName("ToolTipMessageCode")]
public override string ToolTipMessageCode
{get{return this._ToolTipMessageCode;}set{this._ToolTipMessageCode = value;}
}

        一起看看用户控件效果以及封装的属性事件:

        F5看看运行效果:

       Done! 一个控件,减少一半操作量! 在此,本控件当作作者抛砖引玉,看官们可以根据自己实际情况进行数据封装。有效的封装,避免画蛇添足哦~

        最后,由于后续所有重写/重绘控件都在同一个项目使用,而且Dev系统引用文件较多,压缩后源码文件仍然很大,如果有需要源码的朋友,可以微信公众号联系博主,源码可以免费赠予~!有疑问的也可以CALL我一起探讨,最最后,如果觉得本篇博文对您或者身边朋友有帮助的,麻烦点个关注!赠人玫瑰,手留余香,您的支持就是我写作最大的动力,感谢您的关注,期待和您一起探讨!再会!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310864.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php mvc多态实例,asp.net mvc-多态模型绑定

我花了好一天的时间来解决一个密切相关的问题的答案-尽管我不确定这是否是完全相同的问题&#xff0c;但如果有人正在寻找解决同一问题的解决方案&#xff0c;我会在这里发布。就我而言&#xff0c;我有一个抽象的基本类型&#xff0c;用于多种不同的视图模型类型。 因此&#…

洛谷 P1958 上学路线-dfs

输入: 5 4 3 2 2 2 3 4 2输出: 5注意点:这题目输入的时候先输入列&#xff0c;再输入行&#xff0c;这点要注意&#xff0c;然后这个图跟我们二维数组是反过来的&#xff0c;所以题目说得向北走要变成向南走&#xff0c;注意一下细节就好了。 代码如下: #include <io…

.NET Core开发实战(第33课:集成事件:使用RabbitMQ来实现EventBus)--学习笔记(下)...

33 | 集成事件&#xff1a;使用RabbitMQ来实现EventBus为了演示我们的发布和订阅的话&#xff0c;我们在这里的代码做一些稍微的调整namespace GeekTime.API.Application.DomainEventHandlers {public class OrderCreatedDomainEventHandler : IDomainEventHandler<OrderCre…

文本框赋值guide matlab,科学网-Matlab: 学习GUI (使用GUIDE时需注意的几个问题)-刘磊的博文...

在博文《Matlab&#xff1a;学习GUI(一个简单的例子)》(介绍的方法是完全用代码来建立一个GUI&#xff0c;实际上Matlab本身有一个设计GUI的交互系统——GUIDE&#xff0c;用户可以使用该系统更方便的建立自己的GUI.本文将介绍使用GUIDE时常常遇到的几个问题。本文将通过一个简…

洛谷 P1294 高手去散步-邻接矩阵+dfs-求无向图的一条最长路径

输入: 4 6 1 2 10 2 3 20 3 4 30 4 1 40 1 3 50 2 4 60输出: 150邻接矩阵&#xff1a; 代码如下: #include <iostream> using namespace std;int ans -1; const int N 25; int mp[N][N]; bool vis[N]; int n, m; void dfs(int u, int sum) {ans max(ans, sum);for …

论ORM框架—EntityFrameworkCore

欢迎大家阅读《朝夕Net社区技术专刊》我们致力于.NetCore的推广和落地&#xff0c;为更好的帮助大家学习&#xff0c;方便分享干货&#xff0c;特创此刊&#xff01;很高兴你能成为忠实读者&#xff0c;文末福利不要错过哦&#xff01;01PARTORM框架ORM&#xff08;Object Rela…

数字和为sum的方法数-01背包计数问题

给定一个有n个正整数的数组A和一个整数sum,求选择数组A中部分数字和为sum的方案数。 当两种选取方案有一个数字的下标不一样,我们就认为是不同的组成方案。 输入描述: 输入为两行: 第一行为两个正整数n(1 ≤ n ≤ 1000)&#xff0c;sum(1 ≤ sum ≤ 1000) 第二行为n个正整数Ai…

Oracle多租户体系,Oracle12C 多租户管理

--进入cdbsqlplus /nologconn sys/sys as dba--查看数据库基本信息select name,cdb from v$database;--查看容器的相关信息select con_id,name from v$containers;--查看数据文件的路径select con_id,file_name from cdb_data_files order by 1;--显示当前连接容器信息show con…

苏老师首播3小时!超500人观看!录屏!源码!PPT……你要的都在这里!

点击视频 ☝ 回顾直播现场2020年3月25日晚18&#xff1a;30&#xff0c;“盛派周三分享”首次直播交流会&#xff0c;由盛派技术团队带头人Jeffrey&#xff0c;苏震威老师主持、分享&#xff0c;主题是《SCF 框架介绍快速创建项目演示》。此次直播历时3个多小时&#xff0c;500…

oracle错误 904,ORACLE 导出错误 EXP-00008: 遇到 Oracle 错误 904

案例情景——在一次C:\Documents and Settings\Administrator>explsxy/lsxylsxy_dbfileE:\lsxy.dmp ownerlsxyExport:Release 11.2.0.1.0- Production on 星期一 11月 26 14:07:18 2012 Copyright (c) 1982,2009,Oracle and/or its affiliates. All rights reserved.连接到:…

[蓝桥杯][算法提高VIP]数的划分-dp

题目描述 一个正整数可以划分为多个正整数的和&#xff0c;比如n3时&#xff1a; 3&#xff1b;1&#xff0b;2&#xff1b;1&#xff0b;1&#xff0b;1&#xff1b; 共有三种划分方法。 给出一个正整数&#xff0c;问有多少种划分方法。 输入 一个正整数n 数据规模和约定 …

十问十答 GPL 许可证

GPL 是 GNUs General Public License 的缩写&#xff0c;翻译成中文叫 GNU 的通用公共许可证&#xff0c;是最受欢迎的开源许可证之一。它由理查德斯托曼&#xff08;Richard Stallman&#xff09;创建&#xff0c;目的是保护 GNU 软件免于被专有&#xff0c;是基于他「版权向左…

oracle consistent gets,oracle构建一致性读

对于实际的业务系统&#xff0c;通常有一些热点的表&#xff0c;insert和delete的量非常大&#xff0c;这个时候就会发现一些查询语句的逻辑读比较偏高&#xff0c;这时可能就是oracle在构建一致性块的进行的consistentread。下面做一个测试看下&#xff1a;第一步准备数据&…

[蓝桥杯][算法提高VIP]聪明的美食家-dp

题目描述 如果有人认为吃东西只需要嘴巴&#xff0c;那就错了。 都知道舌头有这么一个特性&#xff0c;“由简入奢易&#xff0c;由奢如简难”&#xff08;据好事者考究&#xff0c;此规律也适合许多其他情况&#xff09;。具体而言&#xff0c;如果是甜食&#xff0c;当你吃的…

解析“60k”大佬的19道C#面试题(上)

解析“60k”大佬的19道C#面试题&#xff08;上&#xff09;先略看题目&#xff1a;请简述 async函数的编译方式请简述 Task状态机的实现和工作机制请简述 await的作用和原理&#xff0c;并说明和 GetResult()有什么区别Task和 Thread有区别吗&#xff1f;如果有请简述区别简述 …

oracle秘钥到期,Oracle – 更新加入 – 非密钥保留表

我试图复制一个Ingres“tbl2”中的更新tbl1命令,这在Oracle中并不完全.所以我使用“update(select tbl1 join tbl2 …)”命令.两个表都定义了主键,我认为我的连接唯一标识行,但是我仍然得到“ORA-01779&#xff1a;不能修改映射到非密钥保留表的列”.这里是适当的匿名表定义和我…

dptcpp 题目 2352: [信息学奥赛一本通-T1440]数的划分-dp

题目描述 将整数n分成k份&#xff0c;且每份不能为空&#xff0c;任意两份不能相同(不考虑顺序)。 例如&#xff1a;n7&#xff0c;k3&#xff0c;下面三种分法被认为是相同的。 {1&#xff0c;1&#xff0c;5}&#xff1b;{1&#xff0c;5&#xff0c;1}&#xff1b;{5&…

通过极简模拟框架让你了解ASP.NET Core MVC框架的设计与实现[上篇]

《200行代码&#xff0c;7个对象——让你了解ASP.NET Core框架的本质》让很多读者对ASP.NET Core管道有了真实的了解。在过去很长一段时间中&#xff0c;有很多人私信给我&#xff1a;能否按照相同的方式分析一下MVC框架的设计与实现原理&#xff0c;希望这篇文章能够满足你们的…

linux rsync删文件速度,Linux下使用rsync最快速删除大量文件的方法

要在Linux下删除海量文件的情况&#xff0c;需要删除三层哈希目录下的几十万个文件。这个时候&#xff0c;删除命令rm -rf * 就不好用了&#xff0c;因为要等待的时间太长。所以必须要采取一些非常手段。我们可以使用rsync来实现快速删除大量文件。安装步骤&#xff1a;1、先安…

[蓝桥杯][算法提高VIP]摆花-多重背包计数问题

题目描述 小明的花店新开张&#xff0c;为了吸引顾客&#xff0c;他想在花店的门口摆上一排花&#xff0c;共m盆。通过调查顾客的喜好&#xff0c;小明列出了顾客最喜欢的n种花&#xff0c;从1到n标号。为了在门口展出更多种花&#xff0c;规定第i种花不能超过ai盆&#xff0c;…