缘由

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

说到利器,自然而然的会想到宇宙第一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我一起探讨,最最后,如果觉得本篇博文对您或者身边朋友有帮助的,麻烦点个关注!赠人玫瑰,手留余香,您的支持就是我写作最大的动力,感谢您的关注,期待和您一起探讨!再会!

玩转控件:封装Dev的LabelControl和TextEdit相关推荐

  1. 玩转控件:对Dev的GridControl控件扩展

    缘由 一切实现来源于需求,目的在于不盲目造轮子,有小伙伴儿在看了<玩转控件:对Dev中GridControl控件的封装和扩展>文章后,私信作者说,因公司业务逻辑比较复杂,展示字段比较多,尤 ...

  2. 玩转控件:对Dev中GridControl控件的封装和扩展

    清明节 清明时节雨纷纷 路上行人欲断魂 借问酒家何处有 牧童遥指杏花村 又是一年清明节至,细雨绵绵犹如泪光,树叶随风摆动.... 转眼间,一年又过去了三分之一,疫情的严峻让不少企业就跟清明时节的树叶一 ...

  3. 玩转控件:Fucking ERP之流程图

    前言 首先,跟守护在作者公众号和私信作者催更的朋友们道个歉.疫情的原因,公司从年初到现在一直处于996+的高压模式,导致公众号更新频率较低.而且作者每更新一篇原创公众号,既要对自己沉淀知识负责,也要对 ...

  4. winform 异步弹窗窗体_玩转控件:重写/重绘Dev中MessageBox弹窗控件

    很久没有更新博客了,本想着直接发一篇<手撕ERP>系列,从控件重写.重绘,到框架搭建,再到部分模块实现+业务的.但是每次动手的时候,都觉得难以下手.直接从数据库设计开始吧,模块设计还没定下 ...

  5. 玩转控件:重写/重绘Dev中MessageBox弹窗控件

    很久没有更新博客了,本想着直接发一篇<手撕ERP>系列,从控件重写.重绘,到框架搭建,再到部分模块实现+业务的.但是每次动手的时候,都觉得难以下手.直接从数据库设计开始吧,模块设计还没定下 ...

  6. Silverlight玩转控件(二)——Canvas布局

    在接下来的几篇文章中,我将来介绍Silverlight相关的布局知识. 在Silverlight中,布局主要有三种方式: 1. Cavas 2. StackPanel 3. Grid 在传统的ASP. ...

  7. ExtJs 备忘录(2)—— Form表单(二) [ 控件封装 ]

    前言 本以为可以稳稳当当的工作.安安心心的写文章,结果我做了一件非常疯狂的事情,换新工作一周后辞了--然后去了另外一家公司 - - #,理由就不详说了,总之现在是每天加班到8-9点,虽然如此但是这个团 ...

  8. 基于 next.js + mdx 搭建组件库文档项目(二) -- mdx 控件封装实现组件的演示与 Props 列表

    说明 经过上阶段的配置虽然可以在项目中使用 mdx 语法 来创建页面了,但是我们的组件库有一些定制化的需求:交互式的组件演示.组件 Props 列表展示.这些功能如果可以通过封装来实现,会大大提升开发 ...

  9. 基于JxBrowser的浏览器控件封装实现Java Swing的浏览器集成

    基于JxBrowser的浏览器控件封装实现Java Swing的浏览器集成 背景 实现目标 实现代码 运行效果 完整的代码及依赖jar文件下载 背景 进期客户提出在一个Java Swing项目要集成另 ...

最新文章

  1. [JSOI2018]军训列队
  2. Linux0.1源码分析,《Linux 0.01内核分析与操作系统设计——创造你自己的操作系统》...
  3. 学生电脑哪个牌子好_柳州304不锈钢学生饭盒哪个牌子好_家典美日用品
  4. 数字图像处理实验(2):PROJECT 02-02, Reducing the Number of Gray Levels in an Image
  5. 13、Power Query-逆透视列的解析(上)
  6. 使用Nexus配置Maven私有仓库
  7. 如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集
  8. 1535C. Unstable String
  9. 在Ubuntu 16.04.3 LTS 和 Windows 下安装 Go 环境
  10. 【华为云技术分享】云图说 | 容器交付流水线ContainerOps,助力企业容器化转型
  11. 推荐系统fmlr_推荐系统实践 0x0c FM系列(LR/FM/FFM)
  12. DataTemplate和ControlTemplate的关系
  13. 海豚计算机语言,海豚模拟器 V5.0 多国语言安装版
  14. java 后台跳出提示_小猿圈Java初学者练习小案例:猜数字游戏
  15. 雨林木风工具箱 3.5
  16. 学习FLTK 使用Fl_Menu_Bar
  17. 电池充电器UL1310、启动电源UL2743、电脑风扇507测试报告怎么办理?
  18. Python数据分析的几种绘图方式——数据可视化(附源码)
  19. python词云图_Python快速生成词云图,这是最详细的教程,没有之一!
  20. 强大的 Fresco(加载网络和本地图片)简单使用

热门文章

  1. Struts2和Struts1的不同
  2. 【推荐软件】wingrep
  3. 如何在Xbox One或PlayStation 4上为Skyrim特别版安装Mods
  4. 如何搭建html运行环境,搭建真实的运行环境2019.4.22
  5. 限流算法(记录cyc大佬的专栏)
  6. react connect
  7. 依赖Zookeeper生成全局唯一序列号
  8. 用java写了一个汉诺塔
  9. JDK5.0新特性--可变参数
  10. [C# 项目实战]: 制作一个备忘录(经典)