入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
麻烦博客下方点个【推荐】,谢谢
NuGetInstall-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.Controls11 {12 [ToolBoxItem(false)]13 public partial class UCListVIEwItem : UCControlBase,IListVIEwItem14 {15 private object m_dataSource;16 public object DataSource17 {18 get19 {20 return m_dataSource;21 }22 set23 {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 else49 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 // lblTitle35 // 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 // UCListVIEwItem44 // 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 #endregion59 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 IsMultiple106 {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.@R_404_5553@ = new System.windows.Forms.padding(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 else113 {114 if (m_isMultiple)115 {116 m_selectedSource.Add(selectedItem.DataSource);117 selectedItem.SetSelected(true);118 }119 else120 {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 #endregion147 148 #region 获取cell总数149 /// <summary>150 /// 功能描述:获取cell总数151 /// 作 者:HZH152 /// 创建日期:2019-06-27 16:28:58153 /// 任务编号:POS154 /// </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 {171 if (((IList)m_dataSource).Count > intCount)172 {173 intXCount = (this.panMain.WIDth - 10 - 20) / (item.WIDth + 10);174 m_intCellWIDth = item.WIDth + ((this.panMain.WIDth - 10 - 20) % (item.WIDth + 10)) / intXCount;175 }176 intCount = Math.Max(intCount,((IList)m_dataSource).Count);177 }178 179 CellCount = intCount;180 }181 #endregion
一些事件
private voID panMain_Resize(object sender,EventArgs e) { ReloadGrIDStyle(); }voID m_page_ShowSourceChanged(object currentSource) { this.DataSource = currentSource; }
你会发现,有个ItemType属性,这个用来定义列表呈现那种子元素,这么用的好处就是,当你觉得我写的这个元素控件UCListVIEwItem并不能满足你需求的时候,你可以添加一个自定义控件,并实现接口IListVIEwItem,然后将你自定义的控件指定给这个属性,列表就会呈现出来了,是不是很方便,列表会自动根据你的元素控件的大小来适量调整来填充到列表中的。
还有一个Page属性,这个是用来表示用哪个分页控件,当然你也可以不用,我已经提供了2种分页控件,如果你觉得还是不满足你的话,去参考分页控件那个文章,自己添加一个分页控件吧。
最后的话如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧
总结以上是内存溢出为你收集整理的(四十三)c#Winform自定义控件-Listview全部内容,希望文章能够帮你解决(四十三)c#Winform自定义控件-Listview所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)