轉(zhuǎn)帖|使用教程|編輯:龔雪|2024-03-15 11:19:12.533|閱讀 180 次
概述:本文主要介紹如何在WinForms應(yīng)用界面中用自定義控件豐富界面效果處理,歡迎收藏~
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
Winform界面開發(fā)部分往往也用到了自定義的用戶控件,對(duì)應(yīng)一些特殊的界面或者常用到的一些局部界面內(nèi)容,我們可以使用自定義的用戶控件來(lái)提高界面的統(tǒng)一性,同時(shí)也增強(qiáng)了使用的便利性。如我們Winform界面中用到的分頁(yè)控件、附件顯示內(nèi)容、以及一些公司、部門、菜單的下拉框列表等等,由于重復(fù)多處使用,因此一處封裝多處收益。
PS:給大家推薦一個(gè)C#開發(fā)可以用到的界面組件——DevExpress WinForms,它能完美構(gòu)建流暢、美觀且易于使用的應(yīng)用程序,無(wú)論是Office風(fēng)格的界面,還是分析處理大批量的業(yè)務(wù)數(shù)據(jù),它都能輕松勝任!
DevExpress技術(shù)交流群9:909157416 歡迎一起進(jìn)群討論
之前介紹了不少的控件使用、以及自定義控件的使用例子,如模仿牙醫(yī)管家的軟件界面的部分,來(lái)創(chuàng)建一些自定義部分的內(nèi)容。
根據(jù)其中顯示的內(nèi)容部分,制作了一個(gè)用戶控件,在其中添加一個(gè)LayoutControl方便控制布局,添加一些標(biāo)簽以及設(shè)置了一些圖標(biāo),得到下圖所示。
其中定義的用戶控件的源碼部分,繼承自XtraUserControl用戶控件基類(如果是傳統(tǒng)樣式的Winform界面,可以繼承自UserControl),修改其中源碼增加對(duì)應(yīng)的屬性,方便動(dòng)態(tài)設(shè)置用戶控件的相關(guān)屬性,如顏色塊、項(xiàng)目背景色以及綁定的對(duì)象信息等內(nèi)容。
然后通過(guò)自定義控件的事件或者方法對(duì)界面內(nèi)容進(jìn)行更新處理即可,完成后我們看界面的效果如下所示,較為符合實(shí)際的效果即可。
一般來(lái)說(shuō),一個(gè)窗體用戶控件不多的情況下,Winform界面的效果還是挺好的,如果界面的用戶控件很多,如超過(guò)幾千個(gè),那么可能會(huì)有性能問(wèn)題。動(dòng)態(tài)展現(xiàn)大量歷史號(hào)碼信息的自定義控件的時(shí)候,就會(huì)出現(xiàn)一些句柄創(chuàng)建錯(cuò)誤的問(wèn)題。
控件集合可以通過(guò)布局TableLayoutPanel(表格布局)或者FlowLayoutPanel(順序流布局)來(lái)添加即可,如果利用TableLayoutPanel來(lái)展示,那么需要設(shè)置好每列的寬度或者比例,如下界面所示。
表格的行列定義如下所示。
由于自定義控件,我們需要跟蹤用戶的單擊處理,并且需要把這個(gè)邏輯逐步推動(dòng)到頂級(jí)界面上去進(jìn)行處理,因此需要定義一個(gè)事件信息,如下所示。
/// <summary> /// 事件處理 /// </summary> public EventHandler<ClickEventData> ClickEventHandler { get; set; }
控件的動(dòng)態(tài)添加處理,可以同時(shí)指定它的匿名事件的處理邏輯,從而對(duì)控件的事件進(jìn)行更新。
var controlList = new List<LotteryItemControl2>(); foreach (var info in list) { var control = new LotteryItemControl2(); control.Qi = info.LineNo.ToString("D2"); var numberList = new List<string>() { info.No1.ToString("D2"), info.No2.ToString("D2"), info.No3.ToString("D2"), info.No4.ToString("D2"), info.No5.ToString("D2"), info.No6.ToString("D2"), info.No7.ToString("D2"), }; control.NumberList = numberList; control.BindData(); control.ClickEventHandler += (s, data) => { //遍歷所有的控件統(tǒng)一處理樣式 foreach (var subCtrl in panel.Controls) { if (subCtrl is LotteryItemControl2 lottery) { lottery.SetSelected(data); } } }; controlList.Add(control); } this.panel.Controls.AddRange(controlList.ToArray());
如果我們不喜歡每個(gè)控件都對(duì)事件進(jìn)行一個(gè)層層的處理,也可以引入MediatR來(lái)實(shí)現(xiàn)事件總線的處理。
我們?cè)诔绦騿?dòng)的時(shí)候,注入對(duì)應(yīng)的接口服務(wù)IMediator,那么就可以通過(guò)該靜態(tài)類的 GetService方法獲取對(duì)應(yīng)的注入接口IMediator,我們需要利用該接口來(lái)發(fā)送Send請(qǐng)求/應(yīng)答命令或者發(fā)布Publish消息的處理。
public partial class TestMediatR : BaseForm { private readonly IMediator _mediator; public TestMediatR() { InitializeComponent(); _mediator = ServiceLocator.GetService<IMediator>(); }
MediatR是一個(gè)跨平臺(tái)通過(guò)一種進(jìn)程內(nèi)消息傳遞機(jī)制,進(jìn)行請(qǐng)求/響應(yīng)、命令、查詢、通知和事件的消息傳遞,并通過(guò)C#泛型來(lái)支持消息的智能調(diào)度,其目的是消息發(fā)送和消息處理的解耦。它支持以單播和多播形式使用同步或異步的模式來(lái)發(fā)布消息,創(chuàng)建和偵聽事件。它主要的幾個(gè)對(duì)象:
例如我們發(fā)送消息后,收到應(yīng)答消息結(jié)果,展示在界面中的如下所示。
/// <summary> /// 使用請(qǐng)求、應(yīng)答的消息進(jìn)行測(cè)試,獲得返回結(jié)果后輸出顯示 /// </summary> private async void btnSend_Click(object sender, EventArgs e) { //應(yīng)答處理 var outputMessage = await _mediator.Send(new RetrieveInfoCommandRequest { Text = this.txtSend.Text }); Console.WriteLine(outputMessage.OutputMessage); this.txtReceived.AppendText(outputMessage.OutputMessage + Environment.NewLine); }
如果控件比較多,處理的時(shí)候,刷新的時(shí)候記得移除面板上已經(jīng)添加的控件。
//清空界面 while (panel.Controls.Count > 0) { var controltoremove = panel.Controls[0]; panel.Controls.RemoveAt(0); controltoremove.Dispose(); } panel.Controls.Clear();
例如在附件管理的時(shí)候,對(duì)于一些窗體的信息,我們需要了解該業(yè)務(wù)對(duì)應(yīng)的附件信息有幾個(gè),并且提供入口可以查看或者管理附件列表,那么可以根據(jù)需要封裝一個(gè)自定義附件管理的自定義用戶控件。
在實(shí)際界面應(yīng)用的時(shí)候,由于附件管理的自定義控件已經(jīng)封裝好了,所以在使用的時(shí)候,拖動(dòng)到界面即可,如下界面所示。
我們?cè)谧霾v管理的時(shí)候,就需要大量用到不同的分類的附件信息的展示,如下界面效果所示。
還有就是有時(shí)候,對(duì)于權(quán)限管理里面,部門信息在不少的地方用到,如果每次對(duì)原始的下拉列表處理,那么增加不少工作量,如果把它封裝為自定義控件,和常規(guī)的控件一樣使用即可,就會(huì)很方便,如下界面所示。
它的實(shí)際展示效果如下所示。
單擊下拉列表后,展示部門的列表信息。
同理,用戶控件一旦創(chuàng)建后,我們可以在很多需要的地方直接使用,省卻初始化的一些代碼操作。
我們?cè)诔跏蓟臅r(shí)候,顯示相關(guān)的部門列表,選擇后獲得部門的ID,也可以設(shè)置部門的ID。
/// <summary> /// 部門顯示控件 /// </summary> public partial class DeptControl : XtraUserControl { public string ParentOuID = "-1"; /// <summary> /// 選擇的值發(fā)生變化的時(shí)候 /// </summary> public event EventHandler EditValueChanged; public DeptControl() { InitializeComponent(); this.txtDept.EditValueChanged += new EventHandler(cmbUpperOU_EditValueChanged); } void cmbUpperOU_EditValueChanged(object sender, EventArgs e) { if (EditValueChanged != null) { EditValueChanged(sender, e); } } private async void DeptControl_Load(object sender, EventArgs e) { if (!this.DesignMode) { //限定用戶的選擇級(jí)別 var list = await Portal.gc.GetMyTopGroup(); foreach (OuInfo OuInfo in list) { if (OuInfo != null) { this.ParentOuID = OuInfo.Id.ToString(); } } Init(); } }
需要可以響應(yīng)相關(guān)的編輯事件,用來(lái)觸發(fā)關(guān)聯(lián)的信息變化,如下所示是自定義控件的使用代碼。
public partial class FrmEditUser : BaseEditForm { public FrmEditUser() { InitializeComponent(); this.txtDept.EditValueChanged += new EventHandler(txtDept_EditValueChanged); } void txtDept_EditValueChanged(object sender, EventArgs e) { if (!string.IsNullOrEmpty(txtDept.Value)) { InitManagers(txtDept.Value.ToInt32()); } }
在介紹一個(gè)場(chǎng)景,我們?cè)谝恍┻x擇用戶的界面中,如CRM中對(duì)于分配用戶、工作流中選擇流程用戶的操作中,往往需要選擇系統(tǒng)的人員列表,可以多個(gè)選擇,那么我們可以設(shè)計(jì)界面如下所示。
其中選擇的人員用紅色方框標(biāo)識(shí),這個(gè)部分的用戶和移除圖標(biāo)是自定義控件,界面如下所示。
主要就是方便對(duì)用戶進(jìn)行顯示和移除設(shè)置的一些簡(jiǎn)單的封裝。
在比如在工作流的創(chuàng)建入口中,我們展示相關(guān)可以創(chuàng)建流程的快速入口,通過(guò)一些圖片、文字來(lái)展示工作流程的信息,單擊事件進(jìn)行彈出不同的流程對(duì)話框處理過(guò)程。
這個(gè)過(guò)程主要就是美觀性的要求,是相對(duì)于全部文本信息的單調(diào)有一些改善的效果。
本文轉(zhuǎn)載自:
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: