我們在《SqlSugar開發框架》中,Winform界面開發部分往往也用到了自定義的用戶控制項,對應一些特殊的界面或者常用到的一些局部界面內容,我們可以使用自定義的用戶控制項來提高界面的統一性,同時也增強了使用的便利性。如我們Winform界面中用到的分頁控制項、附件顯示內容、以及一些公司、部門、菜單的下... ...
我們在《SqlSugar開發框架》中,Winform界面開發部分往往也用到了自定義的用戶控制項,對應一些特殊的界面或者常用到的一些局部界面內容,我們可以使用自定義的用戶控制項來提高界面的統一性,同時也增強了使用的便利性。如我們Winform界面中用到的分頁控制項、附件顯示內容、以及一些公司、部門、菜單的下拉框列表等等,由於重覆多處使用,因此一處封裝多處收益。
1、回顧Winform界面中自定義的用戶控制項的處理場景
其實我的關於Winform的開發隨筆,介紹了不少的控制項使用、以及自定義控制項的使用例子,如隨筆《在Winform界面使用自定義用戶控制項及TabelPanel和StackPanel佈局控制項》中介紹到模仿牙醫管家的軟體界面的部分,來創建一些自定義部分的內容。
根據其中顯示的內容部分,製作了一個用戶控制項,在其中添加一個LayoutControl方便控制佈局,添加一些標簽以及設置了一些圖標,得到下圖所示。
其中定義的用戶控制項的源碼部分,繼承自XtraUserControl用戶控制項基類(如果是傳統樣式的Winform界面,可以繼承自UserControl),修改其中源碼增加對應的屬性,方便動態設置用戶控制項的相關屬性,如顏色塊,項目背景色,以及綁定的對象信息等內容。
然後通過自定義控制項的事件或者方法對界面內容進行更新處理即可。完成後我們看界面的效果如下所示,較為符合實際的效果即可。
一般來說,一個窗體用戶控制項不多的情況下,Winform界面的效果還是挺好的,如果界面的用戶控制項很多,如超過幾千個,那麼可能會有性能問題,之前在隨筆《使用Winform開發自定義用戶控制項,以及實現相關自定義事件的處理》中介紹的關於動態展現大量歷史號碼信息的自定義控制項的時候,就會出現一些句柄創建錯誤的問題。
控制項集合可以通過佈局TableLayoutPanel(表格佈局)或者FlowLayoutPanel(順序流佈局)來添加即可。如果利用利用TableLayoutPanel來展示,那麼需要設置好每列的寬度或者比例,如下界面所示。
表格的行列定義如下所示。
由於自定義控制項,我們需要跟蹤用戶的單擊處理,並且需要把這個邏輯逐步推動到頂級界面上去進行處理,因此需要定義一個事件信息,如下所示。
/// <summary> /// 事件處理 /// </summary> public EventHandler<ClickEventData> ClickEventHandler { get; set; }
控制項的動態添加處理,可以同時指定它的匿名事件的處理邏輯,從而對控制項的事件進行更新。
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) => { //遍歷所有的控制項統一處理樣式 foreach (var subCtrl in panel.Controls) { if (subCtrl is LotteryItemControl2 lottery) { lottery.SetSelected(data); } } }; controlList.Add(control); } this.panel.Controls.AddRange(controlList.ToArray());
如果我們不喜歡每個控制項都對事件進行一個層層的處理,我們也可以引入MediatR來實現事件匯流排的處理,如我隨筆介紹《在Winform系統開發中,使用MediatR來實現類似事件匯流排的消息處理》,
MediatR的GitHub項目地址:https://github.com/jbogard/MediatR
我們在程式啟動的時候,註入對應的介面服務IMediator,那麼我們就可以通過該靜態類的 GetService<T>() 方法獲取對應的註入介面IMediator,我們需要利用該介面來發送Send請求/應答命令或者發佈Publish消息的處理。
public partial class TestMediatR : BaseForm { private readonly IMediator _mediator; public TestMediatR() { InitializeComponent(); _mediator = ServiceLocator.GetService<IMediator>(); }
MediatR是一個跨平臺通過一種進程內消息傳遞機制,進行請求/響應、命令、查詢、通知和事件的消息傳遞,並通過C#泛型來支持消息的智能調度,其目的是消息發送和消息處理的解耦。它支持以單播和多播形式使用同步或非同步的模式來發佈消息,創建和偵聽事件。它主要的幾個對象:
IMediator:主要提供Send與Publish方法,需要執行的命令都是通過這兩個方法實現
IRequest、IRequest<T>:命令查詢 | 處理類所繼承的介面,一個有返回類型,一個無返回類型,一個查詢對應一個處理類,程式集只認第一個掃描到的類。
IRequestHandler<in TRequest,TResponse>(實現Handle方法) :命令處理介面。命令查詢 | 處理類繼承它,也可以繼承AsyncRequestHandler(實現抽象Handle方法)、RequestHandler(實現抽象Handle方法)介面
INotification:命令查詢 | 處理類所繼承的介面這個沒有返回,與IRequest不通的是可以對於多個處理類。
INotificationHandler<in TNotification>:與IRequestHandler一樣的只不過這是INotification的處理介面。
例如我們發送消息後,收到應答消息結果,展示在界面中的如下所示。
/// <summary> /// 使用請求、應答的消息進行測試,獲得返回結果後輸出顯示 /// </summary> private async void btnSend_Click(object sender, EventArgs e) { //應答處理 var outputMessage = await _mediator.Send(new RetrieveInfoCommandRequest { Text = this.txtSend.Text }); Console.WriteLine(outputMessage.OutputMessage); this.txtReceived.AppendText(outputMessage.OutputMessage + Environment.NewLine); }
如果控制項比較多,處理的時候,刷新的時候記得移除面板上已經添加的控制項。
//清空界面 while (panel.Controls.Count > 0) { var controltoremove = panel.Controls[0]; panel.Controls.RemoveAt(0); controltoremove.Dispose(); } panel.Controls.Clear();
2、《SqlSugar開發框架》Winform界面中的自定義的用戶控制項的一些處理
例如我們在附件管理的時候,對於一些窗體的信息,我們需要瞭解該業務對應的附件信息有幾個,並且提供入口可以查看或者管理附件列表,那麼我們可以根據需要封裝一個自定義的附件管理的自定義用戶控制項。
在實際界面應用的時候,由於附件管理的自定義控制項已經封裝好了,所以在使用的時候,拖動到界面即可,如下界面所示。
我們在做病歷管理的時候,就需要大量用到不同的分類的附件信息的展示,如下界面效果所示。
還有就是有時候,對於許可權管理裡面,部門信息在不少的地方用到,如果每次對原始的下拉列表處理,那麼增加不少工作量,如果把它封裝為自定義控制項,和常規的控制項一樣使用即可,就會很方便,如下界面所示。
它的實際展示效果如下所示。
單擊下拉列表後,展示部門的列表信息。
同理,用戶控制項一旦創建後,我們可以在很多需要的地方直接使用,省卻初始化的一些代碼操作。
我們在初始化的時候,顯示相關的部門列表,選擇後獲得部門的ID,也可以設置部門的ID。
/// <summary> /// 部門顯示控制項 /// </summary> public partial class DeptControl : XtraUserControl { public string ParentOuID = "-1"; /// <summary> /// 選擇的值發生變化的時候 /// </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) { //限定用戶的選擇級別 var list = await Portal.gc.GetMyTopGroup(); foreach (OuInfo OuInfo in list) { if (OuInfo != null) { this.ParentOuID = OuInfo.Id.ToString(); } } Init(); } }
需要可以響應相關的編輯事件,用來觸發關聯的信息變化,如下所示是自定義控制項的使用代碼。
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()); } }
在介紹一個場景,我們在一些選擇用戶的界面中,如CRM中對於分配用戶、工作流中選擇流程用戶的操作中,往往需要選擇系統的人員列表,可以多個選擇,那麼我們可以設計界面如下所示。
其中選擇的人員用紅色方框標識,這個部分的用戶和移除圖標是自定義控制項,界面如下所示。
主要就是方便對用戶進行顯示和移除設置的一些簡單的封裝。
在比如在工作流的創建入口中,我們展示相關可以創建流程的快速入口,通過一些圖片、文字來展示工作流程的信息,單擊事件進行彈出不同的流程對話框處理過程。
這個過程主要就是美觀性的要求,是相對於全部文本信息的單調有一些改善的效果。
鏈接附註:
如對我們的代碼生成工具有興趣,可以到官網下載使用《代碼生成工具Database2Sharp》。
如需瞭解我們官網對《SqlSugar開發框架》的介紹,可以參考《SqlSugar開發框架》瞭解。
如需閱讀我們對於《SqlSugar開發框架》文章介紹,可以參考博客園的隨筆標簽《SqlSugar隨筆 , WPF隨筆》學習瞭解。
專註於代碼生成工具、.Net/.NetCore 框架架構及軟體開發,以及各種Vue.js的前端技術應用。著有Winform開發框架/混合式開發框架、微信開發框架、Bootstrap開發框架、ABP開發框架、SqlSugar開發框架等框架產品。
轉載請註明出處:撰寫人:伍華聰 http://www.iqidi.com