(四十三)c#Winform自定義控制項-Listview

来源:https://www.cnblogs.com/bfyx/archive/2019/08/22/11393405.html
-Advertisement-
Play Games

前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...


前提

入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果覺得寫的還行,請點個 star 支持一下吧

歡迎前來交流探討: 企鵝群568015492 企鵝群568015492

麻煩博客下方點個【推薦】,謝謝

NuGet

Install-Package HZH_Controls

目錄

https://www.cnblogs.com/bfyx/p/11364884.html

用處及效果

使用分頁控制項效果

不使用分頁控制項效果

準備工作

我們需要元素控制項,需要列表控制項,另外為了具有更好的擴展性,元素控制項實現介面,方便進行擴展

我們用到了分頁控制項,如果你還不瞭解,請移步查看

(十二)c#Winform自定義控制項-分頁控制項

我們這裡的元素控制項用到圓角,故繼承基類控制項UCControlBase,如果不瞭解,請移步查看

(一)c#Winform自定義控制項-基類控制項

開始

添加一個介面,用來約束元素控制項

 1  public interface IListViewItem
 2     {
 3         /// <summary>
 4         /// 數據源
 5         /// </summary>
 6         object DataSource { get; set; }
 7         /// <summary>
 8         /// 選中項事件
 9         /// </summary>
10         event EventHandler SelectedItemEvent;
11         /// <summary>
12         /// 選中處理,一般用以更改選中效果
13         /// </summary>
14         /// <param name="blnSelected">是否選中</param>
15         void SetSelected(bool blnSelected);
16     }

添加一個元素控制項,命名UCListViewItem,我們這裡繼承基類控制項UCControlBase,實現介面IListViewItem

 1 using System;
 2 using System.Collections.Generic;
 3 using System.ComponentModel;
 4 using System.Drawing;
 5 using System.Data;
 6 using System.Linq;
 7 using System.Text;
 8 using System.Windows.Forms;
 9 
10 namespace HZH_Controls.Controls
11 {
12     [ToolboxItem(false)]
13     public partial class UCListViewItem : UCControlBase, IListViewItem
14     {
15         private object m_dataSource;
16         public object DataSource
17         {
18             get
19             {
20                 return m_dataSource;
21             }
22             set
23             {
24                 m_dataSource = value;
25                 lblTitle.Text = value.ToString();
26             }
27         }
28 
29         public event EventHandler SelectedItemEvent;
30         public UCListViewItem()
31         {
32             InitializeComponent();
33             lblTitle.MouseDown += lblTitle_MouseDown;
34         }
35 
36         void lblTitle_MouseDown(object sender, MouseEventArgs e)
37         {
38             if (SelectedItemEvent != null)
39             {
40                 SelectedItemEvent(this, e);
41             }
42         }
43 
44         public void SetSelected(bool blnSelected)
45         {
46             if (blnSelected)
47                 this.FillColor = Color.FromArgb(255, 247, 245);
48             else
49                 this.FillColor = Color.White;
50             this.Refresh();
51         }
52     }
53 }
 1 namespace HZH_Controls.Controls
 2 {
 3     partial class UCListViewItem
 4     {
 5         /// <summary> 
 6         /// 必需的設計器變數。
 7         /// </summary>
 8         private System.ComponentModel.IContainer components = null;
 9 
10         /// <summary> 
11         /// 清理所有正在使用的資源。
12         /// </summary>
13         /// <param name="disposing">如果應釋放托管資源,為 true;否則為 false。</param>
14         protected override void Dispose(bool disposing)
15         {
16             if (disposing && (components != null))
17             {
18                 components.Dispose();
19             }
20             base.Dispose(disposing);
21         }
22 
23         #region 組件設計器生成的代碼
24 
25         /// <summary> 
26         /// 設計器支持所需的方法 - 不要
27         /// 使用代碼編輯器修改此方法的內容。
28         /// </summary>
29         private void InitializeComponent()
30         {
31             this.lblTitle = new System.Windows.Forms.Label();
32             this.SuspendLayout();
33             // 
34             // lblTitle
35             // 
36             this.lblTitle.Dock = System.Windows.Forms.DockStyle.Fill;
37             this.lblTitle.Location = new System.Drawing.Point(0, 0);
38             this.lblTitle.Name = "lblTitle";
39             this.lblTitle.Size = new System.Drawing.Size(107, 96);
40             this.lblTitle.TabIndex = 0;
41             this.lblTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
42             // 
43             // UCListViewItem
44             // 
45             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
46             this.BackColor = System.Drawing.Color.Transparent;
47             this.Controls.Add(this.lblTitle);
48             this.FillColor = System.Drawing.Color.White;
49             this.IsRadius = true;
50             this.IsShowRect = true;
51             this.Name = "UCListViewItem";
52             this.RectColor = System.Drawing.Color.FromArgb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232)))));
53             this.Size = new System.Drawing.Size(107, 96);
54             this.ResumeLayout(false);
55 
56         }
57 
58         #endregion
59 
60         private System.Windows.Forms.Label lblTitle;
61     }
62 }
View Code

然後需要一個列表來顯示元素控制項

添加一個用戶控制項,命名UCListView

一些屬性

  1 int m_intCellWidth = 130;//單元格寬度
  2         int m_intCellHeight = 120;//單元格高度
  3 
  4         private Type m_itemType = typeof(UCListViewItem);
  5 
  6         [Description("單元格類型,如果無法滿足您的需求,你可以自定義單元格控制項,並實現介面IListViewItem"), Category("自定義")]
  7         public Type ItemType
  8         {
  9             get { return m_itemType; }
 10             set
 11             {
 12                 if (!typeof(IListViewItem).IsAssignableFrom(value) || !value.IsSubclassOf(typeof(Control)))
 13                     throw new Exception("單元格控制項沒有繼承實現介面IListViewItem");
 14                 m_itemType = value;
 15             }
 16         }
 17 
 18         private UCPagerControlBase m_page = null;
 19         /// <summary>
 20         /// 翻頁控制項
 21         /// </summary>
 22         [Description("翻頁控制項,如果UCPagerControl不滿足你的需求,請自定義翻頁控制項並繼承UCPagerControlBase"), Category("自定義")]
 23         public UCPagerControlBase Page
 24         {
 25             get { return m_page; }
 26             set
 27             {
 28                 m_page = value;
 29                 if (value != null)
 30                 {
 31                     if (!typeof(IPageControl).IsAssignableFrom(value.GetType()) || !value.GetType().IsSubclassOf(typeof(UCPagerControlBase)))
 32                         throw new Exception("翻頁控制項沒有繼承UCPagerControlBase");
 33                     this.panMain.AutoScroll = false;
 34                     panPage.Visible = true;
 35                     this.Controls.SetChildIndex(panMain, 0);
 36                     m_page.ShowSourceChanged += m_page_ShowSourceChanged;
 37                     m_page.Dock = DockStyle.Fill;
 38                     this.panPage.Controls.Clear();
 39                     this.panPage.Controls.Add(m_page);
 40                     GetCellCount();
 41                     this.DataSource = m_page.GetCurrentSource();
 42                 }
 43                 else
 44                 {
 45                     this.panMain.AutoScroll = true;
 46                     m_page = null;
 47                     panPage.Visible = false;
 48                 }
 49             }
 50         }
 51 
 52 
 53 
 54         private object m_dataSource = null;
 55 
 56         [Description("數據源,如果使用翻頁控制項,請使用翻頁控制項的DataSource"), Category("自定義")]
 57         public object DataSource
 58         {
 59             get { return m_dataSource; }
 60             set
 61             {
 62                 if (value == null)
 63                     return;
 64                 if (!typeof(IList).IsAssignableFrom(value.GetType()))
 65                 {
 66                     throw new Exception("數據源不是有效的數據類型,列表");
 67                 }
 68                 m_dataSource = value;
 69                 ReloadSource();
 70             }
 71         }
 72 
 73         int m_intCellCount = 0;//單元格總數
 74         [Description("單元格總數"), Category("自定義")]
 75         public int CellCount
 76         {
 77             get { return m_intCellCount; }
 78             private set
 79             {
 80                 m_intCellCount = value;
 81                 if (value > 0 && m_page != null)
 82                 {
 83                     m_page.PageSize = m_intCellCount;
 84                     m_page.Reload();
 85                 }
 86             }
 87         }
 88 
 89         private List<object> m_selectedSource = new List<object>();
 90 
 91         [Description("選中的數據"), Category("自定義")]
 92         public List<object> SelectedSource
 93         {
 94             get { return m_selectedSource; }
 95             set
 96             {
 97                 m_selectedSource = value;
 98                 ReloadSource();
 99             }
100         }
101 
102         private bool m_isMultiple = true;
103 
104         [Description("是否多選"), Category("自定義")]
105         public bool IsMultiple
106         {
107             get { return m_isMultiple; }
108             set { m_isMultiple = value; }
109         }
110 
111         [Description("選中項事件"), Category("自定義")]
112         public event EventHandler SelectedItemEvent;
113         public delegate void ReloadGridStyleEventHandle(int intCellCount);
114         /// <summary>
115         /// 樣式改變事件
116         /// </summary>
117         [Description("樣式改變事件"), Category("自定義")]
118         public event ReloadGridStyleEventHandle ReloadGridStyleEvent;

一下輔助函數

  1 #region 重新載入數據源
  2         /// <summary>
  3         /// 功能描述:重新載入數據源
  4         /// 作  者:HZH
  5         /// 創建日期:2019-06-27 16:47:32
  6         /// 任務編號:POS
  7         /// </summary>
  8         public void ReloadSource()
  9         {
 10             ControlHelper.FreezeControl(this, true);
 11             if (this.panMain.Controls.Count <= 0)
 12             {
 13                 ReloadGridStyle();
 14             }
 15             if (m_dataSource == null || ((IList)m_dataSource).Count <= 0)
 16             {
 17                 for (int i = this.panMain.Controls.Count - 1; i >= 0; i--)
 18                 {
 19                     this.panMain.Controls[i].Visible = false;
 20                 }
 21 
 22                 return;
 23             }
 24             int intCount = Math.Min(((IList)m_dataSource).Count, this.panMain.Controls.Count);
 25 
 26             for (int i = 0; i < intCount; i++)
 27             {
 28                 ((IListViewItem)this.panMain.Controls[i]).DataSource = ((IList)m_dataSource)[i];
 29                 if (m_selectedSource.Contains(((IList)m_dataSource)[i]))
 30                 {
 31                     ((IListViewItem)this.panMain.Controls[i]).SetSelected(true);
 32                 }
 33                 else
 34                 {
 35                     ((IListViewItem)this.panMain.Controls[i]).SetSelected(false);
 36                 }
 37                 this.panMain.Controls[i].Visible = true;
 38             }
 39 
 40             for (int i = this.panMain.Controls.Count - 1; i >= intCount; i--)
 41             {
 42                 if (this.panMain.Controls[i].Visible)
 43                     this.panMain.Controls[i].Visible = false;
 44             }
 45             ControlHelper.FreezeControl(this, false);
 46         }
 47         #endregion
 48 
 49         #region 刷新表格
 50         /// <summary>
 51         /// 功能描述:刷新表格樣式
 52         /// 作  者:HZH
 53         /// 創建日期:2019-06-27 16:35:25
 54         /// 任務編號:POS
 55         /// </summary>
 56         public void ReloadGridStyle()
 57         {
 58             Form frmMain = this.FindForm();
 59             if (frmMain != null && !frmMain.IsDisposed && frmMain.Visible && this.Visible)
 60             {
 61                 GetCellCount();
 62                 try
 63                 {
 64                     ControlHelper.FreezeControl(this, true);
 65                     if (this.panMain.Controls.Count < m_intCellCount)
 66                     {
 67                         int intControlsCount = this.panMain.Controls.Count;
 68                         for (int i = 0; i < m_intCellCount - intControlsCount; i++)
 69                         {
 70                             Control uc = (Control)Activator.CreateInstance(m_itemType);
 71                             uc.Margin = new System.Windows.Forms.Padding(5, 5, 5, 5);
 72 
 73                             (uc as IListViewItem).SelectedItemEvent += UCListView_SelectedItemEvent;
 74                             uc.Visible = false;
 75                             this.panMain.Controls.Add(uc);
 76                         }
 77                     }
 78                     else if (this.panMain.Controls.Count > m_intCellCount)
 79                     {
 80                         int intControlsCount = this.panMain.Controls.Count;
 81                         for (int i = intControlsCount - 1; i > m_intCellCount - 1; i--)
 82                         {
 83                             this.panMain.Controls.RemoveAt(i);
 84                         }
 85                     }
 86                     foreach (Control item in this.panMain.Controls)
 87                     {
 88                         item.Size = new Size(m_intCellWidth, m_intCellHeight);
 89                     }
 90                 }
 91                 finally
 92                 {
 93                     ControlHelper.FreezeControl(this, false);
 94                 }
 95                 if (ReloadGridStyleEvent != null)
 96                 {
 97                     ReloadGridStyleEvent(m_intCellCount);
 98                 }
 99             }
100 
101         }
102 
103         void UCListView_SelectedItemEvent(object sender, EventArgs e)
104         {
105             var selectedItem = sender as IListViewItem;
106 
107             if (m_selectedSource.Contains(selectedItem.DataSource))
108             {
109                 m_selectedSource.Remove(selectedItem.DataSource);
110                 selectedItem.SetSelected(false);
111             }
112             else
113             {
114                 if (m_isMultiple)
115                 {
116                     m_selectedSource.Add(selectedItem.DataSource);
117                     selectedItem.SetSelected(true);
118                 }
119                 else
120                 {
121                     if (m_selectedSource.Count > 0)
122                     {
123                         int intCount = Math.Min(((IList)m_dataSource).Count, this.panMain.Controls.Count);
124                         for (int i = 0; i < intCount; i++)
125                         {
126                             var item = ((IListViewItem)this.panMain.Controls[i]);
127                             if (m_selectedSource.Contains(item.DataSource))
128                             {
129                                 item.SetSelected(false);
130                                 break;
131                             }
132                         }
133                     }
134 
135                     m_selectedSource = new List<object>() { selectedItem.DataSource };
136                     selectedItem.SetSelected(true);
137 
138                 }
139             }
140 
141             if (SelectedItemEvent != null)
142             {
143                 SelectedItemEvent(sender, e);
144             }
145         }
146         #endregion
147 
148         #region 獲取cell總數
149         /// <summary>
150         /// 功能描述:獲取cell總數
151         /// 作  者:HZH
152         /// 創建日期:2019-06-27 16:28:58
153         /// 任務編號:POS
154         /// </summary>
155         private void GetCellCount()
156         {
157             if (this.panMain.Width == 0)
158                 return;
159             Control item = (Control)Activator.CreateInstance(m_itemType);
160 
161 
162             int intXCount = (this.panMain.Width - 10) / (item.Width + 10);
163             m_intCellWidth = item.Width + ((this.panMain.Width - 10) % (item.Width + 10)) / intXCount;
164 
165             int intYCount = (this.panMain.Height - 10) / (item.Height + 10);
166             m_intCellHeight = item.Height + ((this.panMain.Height - 10) % (item.Height + 10)) / intYCount;
167             int intCount = intXCount * intYCount;
168 
169             if (Page == null)
170             {
	   

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

-Advertisement-
Play Games
更多相關文章
  • 簡介 Socean.RPC是一個.Net下的高性能RPC框架,框架以高性能、高穩定性為目標,底層基於socket,代碼簡潔,總代碼量大約在2000行,無第三方庫引用,框架性能較高,在雙核i5筆記本上可達10w+每秒的處理量,支持10000長連接消息發送(每秒發10個短消息),均穩定運行,記憶體和cpu ...
  • 在項目的bin\debug\netcoreapp${Version}下麵能夠找到這個${AppName}.runtimeconfig.json文件,簡單來說,它就是用來定義應用程式所用的共用框架(.Net Core App)以及運行時選項 的一個文件。 一個簡單的例子 1、用來決定以哪個版本的.ne ...
  • 導出至Excel是非常常見,我們可以用很多類庫,例如Aspose、NOPI、Interop,在這裡我們使用微軟自家的工具。我的WPF綁定的ObservableCollection<T>集合。 該方法還不止這麼多,還涉及到了1-27 = A-Z 的適配,如以下方法。 最後我們獲取數據給方法,下麵是設計 ...
  • 本文主要參照https://www.bilibili.com/video/av42364337/?p=4 英文幫助文檔:https://identityserver4.readthedocs.io/en/latest/ 中文幫助文檔:http://www.identityserver.com.cn ...
  • 一、Swagger是什麼 Swagger 是一款RESTFUL介面的、基於YAML、JSON語言的文檔線上自動生成、代碼自動生成的工具。 二、如何在項目中加入Swagger Swagger安裝引用 右鍵Web項目依賴項>管理NuGet程式包>在搜索框輸入"Swashbuckle.AspNetCore ...
  • 本次應用DevExpress和C#語言製作了一個批量添加水印的程式,看界面效果圖: 界面中既可以進行文字水印添加,也可以圖片水印添加,同時還可以對水印的位置進行設置,比較實用! 文字水印的具體添加情況,看圖: 還可以文字的預覽: 整個文字水印的預覽: 同時圖片的水印預覽: 最後顯示下圖片的水印效果: ...
  • 摘要 本文將介紹如何通過VS2019創建Xamarin.Forms應用程式,以及如何進行調試。 前言 本文介紹Xamarin.Froms應用程式的創建和調試。 開發環境 1.Visual Studio 2019 2.Xamarin.Forms 3.6.0.344457 創建 1.打開VS2019,選 ...
  • 初學者經常碰到的,即獲取HTML元素集合,迴圈給元素添加事件。在事件響應函數中(event handler)獲取對應的索引。但每次獲取的都是最後一次迴圈的索引。原因是初學者並未理解JavaScript的閉包特性。 1. <!DOCTYPE HTML> 2. <html> 3. <head> 4. < ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...