在Winform界面中使用自定義控制項,豐富界面的效果處理

来源:https://www.cnblogs.com/wuhuacong/p/18036358
-Advertisement-
Play Games

我們在《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 
    

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前言: 在本篇 Taurus.MVC WebMVC 入門開發教程的第四篇文章中, 我們將學習如何實現數據列表的綁定,通過使用 List<Model> 來展示多個數據項。 我們將繼續使用 Taurus.Mvc 命名空間,同時探討如何在視圖中綁定並顯示一個 Model 列表。 步驟1:創建 Model ...
  • 問題背景 有同事聯繫我說,在生產環境上,訪問不了我負責的common服務,然後我去檢查common服務的health endpoint, 沒問題,然後我問了下異常,timeout導致的System.OperationCanceledException。那大概率是客戶端的問題,會不會是埠耗盡,用ne ...
  • 概述:.NET提供多種定時器,如System.Windows.Forms.Timer適用於UI,System.Web.UI.Timer用於Web,System.Diagnostics.Timer用於性能監控,System.Threading.Timer和System.Timers.Timer用於一般 ...
  • 概述:Cron表達式是一種強大的定時任務調度工具,通過配置不同欄位實現靈活的時間規定。在.NET中,Quartz庫提供了簡便的方式配置Cron表達式,實現精準的定時任務調度。這種靈活性和可擴展性使得開發者能夠根據需求輕鬆地制定和管理定時任務,例如每天備份系統日誌或其他重要操作。 Cron表達式詳解 ...
  • 概述:本文介紹了在C#程式開發中如何利用自定義擴展方法測量代碼執行時間。通過使用簡單的Action委托,開發者可以輕鬆獲取代碼塊的執行時間,幫助優化性能、驗證演算法效率以及監控系統性能。這種通用方法提供了一種便捷而有效的方式,有助於提高開發效率和代碼質量。 在軟體開發中,瞭解代碼執行時間是優化程式性能 ...
  • 概述:在WPF中,通過EventHandler可實現基礎和高級的UI更新方式。基礎用法涉及在類中定義事件,併在UI中訂閱以執行更新操作。高級用法藉助Dispatcher類,確保在非UI線程上執行操作後,通過UI線程更新界面。這兩種方法提供了靈活而可靠的UI更新機制。 在WPF(Windows Pre ...
  • 是在MVVM中用來傳遞消息的一種方式。它是在MVVMLight框架中提供的一個實現了IMessenger介面的類,可以用來在ViewModel之間、ViewModel和View之間傳遞消息。 Send 接受一個泛型參數,表示要發送的消息內容。 Register 方法用於註冊某個對象接收消息。 pub ...
  • 在本篇教程中,我們學習瞭如何在 Taurus.MVC WebMVC 中進行數據綁定操作。我們還學習瞭如何使用 ${屬性名稱} CMS 語法來綁定頁面上的元素與 Model 中的屬性。通過這些步驟,我們成功實現了一個簡單的數據綁定示例。 ...
一周排行
    -Advertisement-
    Play Games
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...