緣由
????? ? 俗話說(shuō)的好:"工欲善其事必先利其器",作為軟件攻城獅也是同樣道理,攻城獅開(kāi)發(fā)的軟件目的是簡(jiǎn)化客戶的操作,讓客戶動(dòng)動(dòng)手指就可以完成很多事情,減少人力成本。這也是系統(tǒng)/軟件存在的目的。那對(duì)于攻城獅來(lái)說(shuō)怎么簡(jiǎn)化自己的操作?讓自己也動(dòng)動(dòng)手指就可以減少很多重復(fù)的工作呢?如果你對(duì)此也有同樣的疑問(wèn)或興趣,那就跟作者一起看下去吧!
????????說(shuō)到利器,自然而然的會(huì)想到宇宙第一IDE——Visual Studio 隨著版本的迭代,大大的加快了攻城獅的編碼效率。那對(duì)于我們自己開(kāi)發(fā)的軟件,如何減少重復(fù)操作,加快軟件進(jìn)度呢?這就是作者今日的主題——封裝控件。
????????作者幾年前有幸作為公司代表,到金蝶總部參觀,并學(xué)習(xí)當(dāng)年金蝶最新科技——K3 Cloud,說(shuō)實(shí)話,作者當(dāng)年年輕氣盛,和普遍技術(shù)開(kāi)發(fā)一樣,心高氣傲,對(duì)除自己研發(fā)以外的軟件不屑一顧,覺(jué)得自己才是最流P的!現(xiàn)在好了,善惡終有報(bào),輪到自己爬著學(xué)習(xí)K3 Cloud的控件封裝來(lái)造輪子了...
????????想當(dāng)年,金戈鐵馬,氣吞萬(wàn)里如虎!....現(xiàn)如今,想起來(lái)都是淚...
????????扯遠(yuǎn)了,還是回到本篇的主題造輪子...哦,不!玩轉(zhuǎn)控件!封裝自己的插件吧!
????????今天作者主要介紹的是,封裝Dev的LabelControl和TextEdit。原因很簡(jiǎn)單,說(shuō)的好聽(tīng)就是簡(jiǎn)化自己重復(fù)操作,封裝前,拖控件大法,先拖一個(gè)LabelControl ,完善它的屬性。在拖一個(gè)TextEdit,完善它的屬性,必要時(shí)還要完善它的控件。你以為現(xiàn)在就完了嗎?不對(duì),還要拖動(dòng)一下,看看上下左右的對(duì)齊效果....emmmmm~
實(shí)現(xiàn)
????????Talk is Cheap,Show me the Code!
????????首先我們先新建一個(gè)用戶控件,繼承UserControl,為了減少冗余代碼,作者把命名為BaseControl,后續(xù)所有用戶控件全部繼承此類。
public partial class KzxBaseControl : System.Windows.Forms.UserControl,IControl
????????其中IControl接口主要用來(lái)聲明,控件的一些屬性和事件,部分代碼如下(代碼篇幅較長(zhǎng),有需要公眾號(hào)call我,源碼免費(fèi)贈(zèng)送):
/// <summary>/// 控件事件委托/// </summary>/// <param name="sender">事件發(fā)起者</param>/// <param name="e">事件參數(shù)</param>public delegate void KzxControlOperateEventHandler(object sender, ControlEventArgs e);/// <summary>/// 獲取多語(yǔ)言文本事件委托/// </summary>/// <param name="sender">事件發(fā)起者</param>/// <param name="messageCode">語(yǔ)言標(biāo)識(shí)</param>/// <param name="text">多語(yǔ)言的文本</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>/// 多語(yǔ)言環(huán)境下顯示文本的對(duì)應(yīng)標(biāo)識(shí)/// </summary>string MessageCode { get; set; }/// <summary>/// 設(shè)計(jì)時(shí)的顯示,方便設(shè)計(jì)員工識(shí)別/// </summary>string DesigeCaption { get; set; }/// <summary>/// 控件的唯一標(biāo)識(shí)/// </summary>string Key { get; set; }/// <summary>/// True控件可用,False控件不可用/// </summary>Boolean Enabled { get; set; }/// <summary>/// True控件可見(jiàn),False控件不可見(jiàn)/// </summary>Boolean Visible { get; set; }/// <summary>/// Tag標(biāo)志,用于存儲(chǔ)任何數(shù)據(jù)/// </summary>object Tag { get; set; }/// <summary>/// 設(shè)計(jì)時(shí)的可用性/// </summary>Boolean DesigeEnabled { get; set; }......
????????用戶控件父類,主要集中所有用戶控件的通用屬性、方法和事件,部分代碼如下:
private bool _AllowEdit = true;/// <summary>/// 被引用后允許修改/// true允許,false不允許/// </summary>[Category("驗(yàn)證"), 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>/// 多語(yǔ)言環(huán)境下顯示文本的對(duì)應(yīng)標(biāo)識(shí)/// </summary>[Category("多語(yǔ)言"), Description("MessageCode,多語(yǔ)言環(huán)境下顯示文本的對(duì)應(yīng)標(biāo)識(shí)"), Browsable(true)][McDisplayName("MessageCode")]public virtual string MessageCode{get{return this._MessageCode;}set{this._MessageCode = value;}}private string _DesigeCaption = "顯示標(biāo)題";/// <summary>/// 沒(méi)有多語(yǔ)言的情況下的默認(rèn)顯示標(biāo)題/// </summary>[Category("多語(yǔ)言"), Description("DesigeCaption,沒(méi)有多語(yǔ)言的情況下的默認(rèn)顯示標(biāo)題"), Browsable(true)][McDisplayName("DesigeCaption")]public virtual string DesigeCaption{get{return this._DesigeCaption;}set{this._DesigeCaption = value;}}private string _Key = string.Empty;/// <summary>/// 控件的唯一標(biāo)識(shí)/// </summary>[Category("數(shù)據(jù)"), Description("Key,控件的唯一標(biāo)識(shí)"), 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>/// 設(shè)計(jì)時(shí)的可用性/// </summary>[Category("特性"), Description("DesigeEnabled,設(shè)計(jì)時(shí)的可用性"), Browsable(true)][McDisplayName("DesigeEnabled")]public virtual bool DesigeEnabled{get{return this._DesigeEnabled;}set{this._DesigeEnabled = value;//this.Enabled = value;}}private bool _DesigeVisible = true;/// <summary>/// 設(shè)計(jì)時(shí)可見(jiàn)性/// </summary>[Category("特性"), Description("DesigeVisible,設(shè)計(jì)時(shí)可見(jiàn)性"), 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>
/// 觸發(fā)控件事件
/// </summary>
/// <param name="sender">事件發(fā)起者</param>
/// <param name="eventName">事件名稱</param>
/// <param name="e">事件參數(shù)</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>
/// 獲取多語(yǔ)言文本
/// </summary>
/// <param name="messageCode">語(yǔ)言文本標(biāo)識(shí)</param>
/// <param name="defaultMessage">默認(rèn)的文本</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();
}
????????介紹完基類,我們新建在新建要給用戶控件來(lái)繼承它,并實(shí)現(xiàn)業(yè)務(wù)需求:
/// <summary>/// 文本框驗(yàn)證/// </summary>[ToolboxBitmapAttribute(typeof(Bitmap), "文本框")]public partial class KzxTextBox : KzxBaseControl
????????布局方面,應(yīng)自己要求,氣運(yùn)丹田,使出拖控件大法!
????????此處無(wú)需做任何屬性、事件設(shè)置。只需把我們?nèi)粘3S玫降膶傩浴⑹录?#xff0c;用特性標(biāo)記起來(lái)即可。部分代碼如下:
private DevExpress.XtraEditors.Controls.BorderStyles _BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.Default;
/// <summary>
/// 邊框顯示格式
/// </summary>
[Category("數(shù)據(jù)格式"),?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>
/// 沒(méi)有多語(yǔ)言的情況下的默認(rèn)顯示標(biāo)題
/// </summary>
[Category("多語(yǔ)言"), Description("DesigeCaption,沒(méi)有多語(yǔ)言的情況下的默認(rèn)顯示標(biāo)題"), 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("驗(yàn)證"), Description("IsNull,可空性"), Browsable(true)]
[McDisplayName("IsNull")]
public override bool IsNull
{get{SetBackColor();return this._IsNull;}set{this._IsNull = value;SetBackColor();}
}/// <summary>
/// 只讀性
/// </summary>
[Category("驗(yàn)證"), 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>
/// 可錄入的最大長(zhǎng)度
/// </summary>
[Category("驗(yàn)證"), Description("MaxLength,可錄入的最大長(zhǎng)度"), Browsable(true)]
[McDisplayName("MaxLength")]
public override int MaxLength
{get{return maxLength;}set{maxLength = value;}
}private Int32 _CaptionLabelWidth = 75;
/// <summary>
/// 顯示標(biāo)題寬度
/// </summary>
[Category("外觀"), Description("CaptionLabelWidth,顯示標(biāo)題寬度"), 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>
/// 數(shù)據(jù)長(zhǎng)度不能超過(guò)數(shù)據(jù)庫(kù)長(zhǎng)度提示文本
/// </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>
/// 提示多語(yǔ)言標(biāo)識(shí)
/// </summary>
[Category("汽泡提示"), Description("ToolTipMessageCode,提示信息多語(yǔ)言標(biāo)識(shí)"), Browsable(true)]
[McDisplayName("ToolTipMessageCode")]
public override string ToolTipMessageCode
{get{return this._ToolTipMessageCode;}set{this._ToolTipMessageCode = value;}
}
????????一起看看用戶控件效果以及封裝的屬性事件:
????????F5看看運(yùn)行效果:
????? ?Done! 一個(gè)控件,減少一半操作量!?在此,本控件當(dāng)作作者拋磚引玉,看官們可以根據(jù)自己實(shí)際情況進(jìn)行數(shù)據(jù)封裝。有效的封裝,避免畫(huà)蛇添足哦~
????????最后,由于后續(xù)所有重寫(xiě)/重繪控件都在同一個(gè)項(xiàng)目使用,而且Dev系統(tǒng)引用文件較多,壓縮后源碼文件仍然很大,如果有需要源碼的朋友,可以微信公眾號(hào)聯(lián)系博主,源碼可以免費(fèi)贈(zèng)予~!有疑問(wèn)的也可以CALL我一起探討,最最后,如果覺(jué)得本篇博文對(duì)您或者身邊朋友有幫助的,麻煩點(diǎn)個(gè)關(guān)注!贈(zèng)人玫瑰,手留余香,您的支持就是我寫(xiě)作最大的動(dòng)力,感謝您的關(guān)注,期待和您一起探討!再會(huì)!
總結(jié)
以上是生活随笔為你收集整理的玩转控件:封装Dev的LabelControl和TextEdit的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。