官网
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
目录
https://www.cnblogs.com/bfyx/p/11364884.html
准备工作
表格控件将拆分为2部分,1:行元素控件,2:列表控件
为了具有更好的扩展性,更加的open,使用接口对行元素进行约束,当行样式或功能不满足你的需求的时候,可以自定义一个行元素,实现接口控件,然后将类型指定给列表控件即可
表格控件用到了分页控件,如果你还没有对分页控件进行了解,请移步查看
开始
定义一些辅助东西
1 public class DataGridViewCellEntity 2 { 3 public string Title { get; set; } 4 public int Width { get; set; } 5 public System.Windows.Forms.SizeType WidthType { get; set; } 6 7 }
1 public class DataGridViewEventArgs : EventArgs 2 { 3 public Control CellControl { get; set; } 4 public int CellIndex { get; set; } 5 public int RowIndex { get; set; } 6 7 8 }
1 [Serializable] 2 [ComVisible(true)] 3 public delegate void DataGridViewEventHandler(object sender, DataGridViewEventArgs e);
1 public class DataGridViewColumnEntity 2 { 3 public string HeadText { get; set; } 4 public int Width { get; set; } 5 public System.Windows.Forms.SizeType WidthType { get; set; } 6 public string DataField { get; set; } 7 public Func<object, string> Format { get; set; } 8 }
定义行接口
1 public interface IDataGridViewRow 2 { 3 /// <summary> 4 /// CheckBox选中事件 5 /// </summary> 6 event DataGridViewEventHandler CheckBoxChangeEvent; 7 /// <summary> 8 /// 点击单元格事件 9 /// </summary> 10 event DataGridViewEventHandler CellClick; 11 /// <summary> 12 /// 数据源改变事件 13 /// </summary> 14 event DataGridViewEventHandler SourceChanged; 15 /// <summary> 16 /// 列参数,用于创建列数和宽度 17 /// </summary> 18 List<DataGridViewColumnEntity> Columns { get; set; } 19 bool IsShowCheckBox { get; set; } 20 /// <summary> 21 /// 是否选中 22 /// </summary> 23 bool IsChecked { get; set; } 24 25 /// <summary> 26 /// 数据源 27 /// </summary> 28 object DataSource { get; set; } 29 /// <summary> 30 /// 添加单元格元素,仅做添加控件操作,不做数据绑定,数据绑定使用BindingCells 31 /// </summary> 32 void ReloadCells(); 33 /// <summary> 34 /// 绑定数据到Cell 35 /// </summary> 36 /// <param name="intIndex">cell下标</param> 37 /// <returns>返回true则表示已处理过,否则将进行默认绑定(通常只针对有Text值的控件)</returns> 38 void BindingCellData(); 39 /// <summary> 40 /// 设置选中状态,通常为设置颜色即可 41 /// </summary> 42 /// <param name="blnSelected">是否选中</param> 43 void SetSelect(bool blnSelected); 44 }
创建行控件
添加一个用户控件,命名UCDataGridViewRow,实现接口IDataGridViewRow
属性
1 #region 属性 2 public event DataGridViewEventHandler CheckBoxChangeEvent; 3 4 public event DataGridViewEventHandler CellClick; 5 6 public event DataGridViewEventHandler SourceChanged; 7 8 public List<DataGridViewColumnEntity> Columns 9 { 10 get; 11 set; 12 } 13 14 public object DataSource 15 { 16 get; 17 set; 18 } 19 20 public bool IsShowCheckBox 21 { 22 get; 23 set; 24 } 25 private bool m_isChecked; 26 public bool IsChecked 27 { 28 get 29 { 30 return m_isChecked; 31 } 32 33 set 34 { 35 if (m_isChecked != value) 36 { 37 m_isChecked = value; 38 (this.panCells.Controls.Find("check", false)[0] as UCCheckBox).Checked = value; 39 } 40 } 41 } 42 43 44 #endregion
实现接口
1 public void BindingCellData() 2 { 3 for (int i = 0; i < Columns.Count; i++) 4 { 5 DataGridViewColumnEntity com = Columns[i]; 6 var cs = this.panCells.Controls.Find("lbl_" + com.DataField, false); 7 if (cs != null && cs.Length > 0) 8 { 9 var pro = DataSource.GetType().GetProperty(com.DataField); 10 if (pro != null) 11 { 12 var value = pro.GetValue(DataSource, null); 13 if (com.Format != null) 14 { 15 cs[0].Text = com.Format(value); 16 } 17 else 18 { 19 cs[0].Text = value.ToStringExt(); 20 } 21 } 22 } 23 } 24 } 25 26 public void SetSelect(bool blnSelected) 27 { 28 if (blnSelected) 29 { 30 this.BackColor = Color.FromArgb(255, 247, 245); 31 } 32 else 33 { 34 this.BackColor = Color.Transparent; 35 } 36 } 37 38 public void ReloadCells() 39 { 40 try 41 { 42 ControlHelper.FreezeControl(this, true); 43 this.panCells.Controls.Clear(); 44 this.panCells.ColumnStyles.Clear(); 45 46 int intColumnsCount = Columns.Count(); 47 if (Columns != null && intColumnsCount > 0) 48 { 49 if (IsShowCheckBox) 50 { 51 intColumnsCount++; 52 } 53 this.panCells.ColumnCount = intColumnsCount; 54 for (int i = 0; i < intColumnsCount; i++) 55 { 56 Control c = null; 57 if (i == 0 && IsShowCheckBox) 58 { 59 this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Absolute, 30F)); 60 61 UCCheckBox box = new UCCheckBox(); 62 box.Name = "check"; 63 box.TextValue = ""; 64 box.Size = new Size(30, 30); 65 box.Dock = DockStyle.Fill; 66 box.CheckedChangeEvent += (a, b) => 67 { 68 IsChecked = box.Checked; 69 if (CheckBoxChangeEvent != null) 70 { 71 CheckBoxChangeEvent(a, new DataGridViewEventArgs() 72 { 73 CellControl = box, 74 CellIndex = 0 75 }); 76 } 77 }; 78 c = box; 79 } 80 else 81 { 82 var item = Columns[i - (IsShowCheckBox ? 1 : 0)]; 83 this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width)); 84 85 Label lbl = new Label(); 86 lbl.Tag = i - (IsShowCheckBox ? 1 : 0); 87 lbl.Name = "lbl_" + item.DataField; 88 lbl.Font = new Font("微软雅黑", 12); 89 lbl.ForeColor = Color.Black; 90 lbl.AutoSize = false; 91 lbl.Dock = DockStyle.Fill; 92 lbl.TextAlign = ContentAlignment.MiddleCenter; 93 lbl.MouseDown += (a, b) => 94 { 95 Item_MouseDown(a, b); 96 }; 97 c = lbl; 98 } 99 this.panCells.Controls.Add(c, i, 0); 100 } 101 102 } 103 } 104 finally 105 { 106 ControlHelper.FreezeControl(this, false); 107 } 108 }
节点选中事件
1 void Item_MouseDown(object sender, MouseEventArgs e) 2 { 3 if (CellClick != null) 4 { 5 CellClick(sender, new DataGridViewEventArgs() 6 { 7 CellControl = this, 8 CellIndex = (sender as Control).Tag.ToInt() 9 }); 10 } 11 }
完整的代码
1 // 版权所有 黄正辉 交流群:568015492 QQ:623128629 2 // 文件名称:UCDataGridViewRow.cs 3 // 创建日期:2019-08-15 15:59:31 4 // 功能描述:DataGridView 5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 6 using System; 7 using System.Collections.Generic; 8 using System.ComponentModel; 9 using System.Drawing; 10 using System.Data; 11 using System.Linq; 12 using System.Text; 13 using System.Windows.Forms; 14 15 namespace HZH_Controls.Controls 16 { 17 [ToolboxItem(false)] 18 public partial class UCDataGridViewRow : UserControl, IDataGridViewRow 19 { 20 21 #region 属性 22 public event DataGridViewEventHandler CheckBoxChangeEvent; 23 24 public event DataGridViewEventHandler CellClick; 25 26 public event DataGridViewEventHandler SourceChanged; 27 28 public List<DataGridViewColumnEntity> Columns 29 { 30 get; 31 set; 32 } 33 34 public object DataSource 35 { 36 get; 37 set; 38 } 39 40 public bool IsShowCheckBox 41 { 42 get; 43 set; 44 } 45 private bool m_isChecked; 46 public bool IsChecked 47 { 48 get 49 { 50 return m_isChecked; 51 } 52 53 set 54 { 55 if (m_isChecked != value) 56 { 57 m_isChecked = value; 58 (this.panCells.Controls.Find("check", false)[0] as UCCheckBox).Checked = value; 59 } 60 } 61 } 62 63 64 #endregion 65 66 public UCDataGridViewRow() 67 { 68 InitializeComponent(); 69 } 70 71 public void BindingCellData() 72 { 73 for (int i = 0; i < Columns.Count; i++) 74 { 75 DataGridViewColumnEntity com = Columns[i]; 76 var cs = this.panCells.Controls.Find("lbl_" + com.DataField, false); 77 if (cs != null && cs.Length > 0) 78 { 79 var pro = DataSource.GetType().GetProperty(com.DataField); 80 if (pro != null) 81 { 82 var value = pro.GetValue(DataSource, null); 83 if (com.Format != null) 84 { 85 cs[0].Text = com.Format(value); 86 } 87 else 88 { 89 cs[0].Text = value.ToStringExt(); 90 } 91 } 92 } 93 } 94 } 95 96 void Item_MouseDown(object sender, MouseEventArgs e) 97 { 98 if (CellClick != null) 99 { 100 CellClick(sender, new DataGridViewEventArgs() 101 { 102 CellControl = this, 103 CellIndex = (sender as Control).Tag.ToInt() 104 }); 105 } 106 } 107 108 public void SetSelect(bool blnSelected) 109 { 110 if (blnSelected) 111 { 112 this.BackColor = Color.FromArgb(255, 247, 245); 113 } 114 else 115 { 116 this.BackColor = Color.Transparent; 117 } 118 } 119 120 public void ReloadCells() 121 { 122 try 123 { 124 ControlHelper.FreezeControl(this, true); 125 this.panCells.Controls.Clear(); 126 this.panCells.ColumnStyles.Clear(); 127 128 int intColumnsCount = Columns.Count(); 129 if (Columns != null && intColumnsCount > 0) 130 { 131 if (IsShowCheckBox) 132 { 133 intColumnsCount++; 134 } 135 this.panCells.ColumnCount = intColumnsCount; 136 for (int i = 0; i < intColumnsCount; i++) 137 { 138 Control c = null; 139 if (i == 0 && IsShowCheckBox) 140 { 141 this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Absolute, 30F)); 142 143 UCCheckBox box = new UCCheckBox(); 144 box.Name = "check"; 145 box.TextValue = ""; 146 box.Size = new Size(30, 30); 147 box.Dock = DockStyle.Fill; 148 box.CheckedChangeEvent += (a, b) => 149 { 150 IsChecked = box.Checked; 151 if (CheckBoxChangeEvent != null) 152 { 153 CheckBoxChangeEvent(a, new DataGridViewEventArgs() 154 { 155 CellControl = box, 156 CellIndex = 0 157 }); 158 } 159 }; 160 c = box; 161 } 162 else 163 { 164 var item = Columns[i - (IsShowCheckBox ? 1 : 0)]; 165 this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width)); 166 167 Label lbl = new Label(); 168 lbl.Tag = i - (IsShowCheckBox ? 1 : 0); 169 lbl.Name = "lbl_" + item.DataField; 170 lbl.Font = new Font("微软雅黑", 12); 171 lbl.ForeColor = Color.Black; 172 lbl.AutoSize = false; 173 lbl.Dock = DockStyle.Fill; 174 lbl.TextAlign = ContentAlignment.MiddleCenter; 175 lbl.MouseDown += (a, b) => 176 { 177 Item_MouseDown(a, b); 178 }; 179 c = lbl; 180 } 181 this.panCells.Controls.Add(c, i, 0); 182 } 183 184 } 185 } 186 finally 187 { 188 ControlHelper.FreezeControl(this, false); 189 } 190 } 191 192 193 } 194 }
1 namespace HZH_Controls.Controls 2 { 3 partial class UCDataGridViewRow 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.ucSplitLine_H1 = new HZH_Controls.Controls.UCSplitLine_H(); 32 this.panCells = new System.Windows.Forms.TableLayoutPanel(); 33 this.SuspendLayout(); 34 // 35 // ucSplitLine_H1 36 // 37 this.ucSplitLine_H1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232))))); 38 this.ucSplitLine_H1.Dock = System.Windows.Forms.DockStyle.Bottom; 39 this.ucSplitLine_H1.Location = new System.Drawing.Point(0, 55); 40 this.ucSplitLine_H1.Name = "ucSplitLine_H1"; 41 this.ucSplitLine_H1.Size = new System.Drawing.Size(661, 1); 42 this.ucSplitLine_H1.TabIndex = 0; 43 this.ucSplitLine_H1.TabStop = false; 44 // 45 // panCells 46 // 47 this.panCells.ColumnCount = 1; 48 this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); 49 this.panCells.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F)); 50 this.panCells.Dock = System.Windows.Forms.DockStyle.Fill; 51 this.panCells.Location = new System.Drawing.Point(0, 0); 52 this.panCells.Name = "panCells"; 53 this.panCells.RowCount = 1; 54 this.panCells.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); 55 this.panCells.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); 56 this.panCells.Size = new System.Drawing.Size(661, 55); 57 this.panCells.TabIndex = 1; 58 // 59 // UCDataGridViewItem 60 // 61 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; 62 this.BackColor = System.Drawing.Color.White; 63 this.Controls.Add(this.panCells); 64 this.Controls.Add(this.ucSplitLine_H1); 65 this.Name = "UCDataGridViewItem"; 66 this.Size = new System.Drawing.Size(661, 56); 67 this.ResumeLayout(false); 68 69 } 70 71 #endregion 72 73 private UCSplitLine_H ucSplitLine_H1; 74 private System.Windows.Forms.TableLayoutPanel panCells; 75 } 76 }
接下来就是列表控件了
添加一个用户控件,命名UCDataGridView
属性
1 #region 属性 2 private Font m_headFont = new Font("微软雅黑", 12F); 3 /// <summary> 4 /// 标题字体 5 /// </summary> 6 [Description("标题字体"), Category("自定义")] 7 public Font HeadFont 8 { 9 get { return m_headFont; } 10 set { m_headFont = value; } 11 } 12 private Color m_headTextColor = Color.Black; 13 /// <summary> 14 /// 标题字体颜色 15 /// </summary> 16 [Description("标题文字颜色"), Category("自定义")] 17 public Color HeadTextColor 18 { 19 get { return m_headTextColor; } 20 set { m_headTextColor = value; } 21 } 22 23 private bool m_isShowHead = true; 24 /// <summary> 25 /// 是否显示标题 26 /// </summary> 27 [Description("是否显示标题"), Category("自定义")] 28 public bool IsShowHead 29 { 30 get { return m_isShowHead; } 31 set 32 { 33 m_isShowHead = value; 34 panHead.Visible = value; 35 if (m_page != null) 36 { 37 ResetShowCount(); 38 m_page.PageSize = m_showCount; 39 } 40 } 41 } 42 private int m_headHeight = 40; 43 /// <summary> 44 /// 标题高度 45 /// </summary> 46 [Description("标题高度"), Category("自定义")] 47 public int HeadHeight 48 { 49 get { return m_headHeight; } 50 set 51 { 52 m_headHeight = value; 53 panHead.Height = value; 54 } 55 } 56 57 private bool m_isShowCheckBox = false; 58 /// <summary> 59 /// 是否显示复选框 60 /// </summary> 61 [Description("是否显示选择框"), Category("自定义")] 62 public bool IsShowCheckBox 63 { 64 get { return m_isShowCheckBox; } 65 set 66 { 67 if (value != m_isShowCheckBox) 68 { 69 m_isShowCheckBox = value; 70 LoadColumns(); 71 } 72 } 73 } 74 75 private int m_rowHeight = 40; 76 /// <summary> 77 /// 行高 78 /// </summary> 79 [Description("数据行高"), Category("自定义")] 80 public int RowHeight 81 { 82 get { return m_rowHeight; } 83 set { m_rowHeight = value; } 84 } 85 86 private int m_showCount = 0; 87 /// <summary> 88 /// 89 /// </summary> 90 [Description("可显示个数"), Category("自定义")] 91 public int ShowCount 92 { 93 get { return m_showCount; } 94 private set 95 { 96 m_showCount = value; 97 if (m_page != null) 98 { 99 m_page.PageSize = value; 100 } 101 } 102 } 103 104 private List<DataGridViewColumnEntity> m_columns; 105 /// <summary> 106 /// 列 107 /// </summary> 108 [Description("列"), Category("自定义")] 109 public List<DataGridViewColumnEntity> Columns 110 { 111 get { return m_columns; } 112 set 113 { 114 m_columns = value; 115 LoadColumns(); 116 } 117 } 118 119 private object m_dataSource; 120 /// <summary> 121 /// 数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource 122 /// </summary> 123 [Description("数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource"), Category("自定义")] 124 public object DataSource 125 { 126 get { return m_dataSource; } 127 set 128 { 129 if (value == null) 130 return; 131 if (!(m_dataSource is DataTable) && (!typeof(IList).IsAssignableFrom(value.GetType()))) 132 { 133 throw new Exception("数据源不是有效的数据类型,请使用Datatable或列表"); 134 } 135 136 m_dataSource = value; 137 ReloadSource(); 138 } 139 } 140 141 public List<IDataGridViewRow> Rows { get; private set; } 142 143 private Type m_rowType = typeof(UCDataGridViewRow); 144 /// <summary> 145 /// 行元素类型,默认UCDataGridViewItem 146 /// </summary> 147 [Description("行控件类型,默认UCDataGridViewRow,如果不满足请自定义行控件实现接口IDataGridViewRow"), Category("自定义")] 148 public Type RowType 149 { 150 get { return m_rowType; } 151 set 152 { 153 if (value == null) 154 return; 155 if (!typeof(IDataGridViewRow).IsAssignableFrom(value) || !value.IsSubclassOf(typeof(Control))) 156 throw new Exception("行控件没有实现IDataGridViewRow接口"); 157 m_rowType = value; 158 } 159 } 160 IDataGridViewRow m_selectRow = null; 161 /// <summary> 162 /// 选中的节点 163 /// </summary> 164 [Description("选中行"), Category("自定义")] 165 public IDataGridViewRow SelectRow 166 { 167 get { return m_selectRow; } 168 private set { m_selectRow = value; } 169 } 170 171 172 /// <summary> 173 /// 选中的行,如果显示CheckBox,则以CheckBox选中为准 174 /// </summary> 175 [Description("选中的行,如果显示CheckBox,则以CheckBox选中为准"), Category("自定义")] 176 public List<IDataGridViewRow> SelectRows 177 { 178 get 179 { 180 if (m_isShowCheckBox) 181 { 182 return Rows.FindAll(p => p.IsChecked); 183 } 184 else 185 return new List<IDataGridViewRow>() { m_selectRow }; 186 } 187 } 188 189 190 private UCPagerControlBase m_page = null; 191 /// <summary> 192 /// 翻页控件 193 /// </summary> 194 [Description("翻页控件,如果UCPagerControl不满足你的需求,请自定义翻页控件并继承UCPagerControlBase"), Category("自定义")] 195 public UCPagerControlBase Page 196 { 197 get { return m_page; } 198 set 199 { 200 m_page = value; 201 if (value != null) 202 { 203 if (!typeof(IPageControl).IsAssignableFrom(value.GetType()) || !value.GetType().IsSubclassOf(typeof(UCPagerControlBase))) 204 throw new Exception("翻页控件没有继承UCPagerControlBase"); 205 panPage.Visible = value != null; 206 m_page.ShowSourceChanged += page_ShowSourceChanged; 207 m_page.Dock = DockStyle.Fill; 208 this.panPage.Controls.Clear(); 209 this.panPage.Controls.Add(m_page); 210 ResetShowCount(); 211 m_page.PageSize = ShowCount; 212 this.DataSource = m_page.GetCurrentSource(); 213 } 214 else 215 { 216 m_page = null; 217 } 218 } 219 } 220 221 void page_ShowSourceChanged(object currentSource) 222 { 223 this.DataSource = currentSource; 224 } 225 226 #region 事件 227 [Description("选中标题选择框事件"), Category("自定义")] 228 public EventHandler HeadCheckBoxChangeEvent; 229 [Description("标题点击事件"), Category("自定义")] 230 public EventHandler HeadColumnClickEvent; 231 [Description("项点击事件"), Category("自定义")] 232 public event DataGridViewEventHandler ItemClick; 233 [Description("数据源改变事件"), Category("自定义")] 234 public event DataGridViewEventHandler SourceChanged; 235 #endregion 236 #endregion
一些私有的方法
1 #region 私有方法 2 #region 加载column 3 /// <summary> 4 /// 功能描述:加载column 5 /// 作 者:HZH 6 /// 创建日期:2019-08-08 17:51:50 7 /// 任务编号:POS 8 /// </summary> 9 private void LoadColumns() 10 { 11 try 12 { 13 if (DesignMode) 14 { return; } 15 16 ControlHelper.FreezeControl(this.panHead, true); 17 this.panColumns.Controls.Clear(); 18 this.panColumns.ColumnStyles.Clear(); 19 20 if (m_columns != null && m_columns.Count() > 0) 21 { 22 int intColumnsCount = m_columns.Count(); 23 if (m_isShowCheckBox) 24 { 25 intColumnsCount++; 26 } 27 this.panColumns.ColumnCount = intColumnsCount; 28 for (int i = 0; i < intColumnsCount; i++) 29 { 30 Control c = null; 31 if (i == 0 && m_isShowCheckBox) 32 { 33 this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Absolute, 30F)); 34 35 UCCheckBox box = new UCCheckBox(); 36 box.TextValue = ""; 37 box.Size = new Size(30, 30); 38 box.CheckedChangeEvent += (a, b) => 39 { 40 Rows.ForEach(p => p.IsChecked = box.Checked); 41 if (HeadCheckBoxChangeEvent != null) 42 { 43 HeadCheckBoxChangeEvent(a, b); 44 } 45 }; 46 c = box; 47 } 48 else 49 { 50 var item = m_columns[i - (m_isShowCheckBox ? 1 : 0)]; 51 this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width)); 52 Label lbl = new Label(); 53 lbl.Name = "dgvColumns_" + i; 54 lbl.Text = item.HeadText; 55 lbl.Font = m_headFont; 56 lbl.ForeColor = m_headTextColor; 57 lbl.TextAlign = ContentAlignment.MiddleCenter; 58 lbl.AutoSize = false; 59 lbl.Dock = DockStyle.Fill; 60 lbl.MouseDown += (a, b) => 61 { 62 if (HeadColumnClickEvent != null) 63 { 64 HeadColumnClickEvent(a, b); 65 } 66 }; 67 c = lbl; 68 } 69 this.panColumns.Controls.Add(c, i, 0); 70 } 71 72 } 73 } 74 finally 75 { 76 ControlHelper.FreezeControl(this.panHead, false); 77 } 78 } 79 #endregion 80 81 /// <summary> 82 /// 功能描述:获取显示个数 83 /// 作 者:HZH 84 /// 创建日期:2019-03-05 10:02:58 85 /// 任务编号:POS 86 /// </summary> 87 /// <returns>返回值</returns> 88 private void ResetShowCount() 89 { 90 if (DesignMode) 91 { return; } 92 ShowCount = this.panRow.Height / (m_rowHeight); 93 int intCha = this.panRow.Height % (m_rowHeight); 94 m_rowHeight += intCha / ShowCount; 95 } 96 #endregion
几个事件
1 #region 事件 2 void RowSourceChanged(object sender, DataGridViewEventArgs e) 3 { 4 if (SourceChanged != null) 5 SourceChanged(sender, e); 6 } 7 private void SetSelectRow(Control item, DataGridViewEventArgs e) 8 { 9 try 10 { 11 ControlHelper.FreezeControl(this, true); 12 if (item == null) 13 return; 14 if (item.Visible == false) 15 return; 16 this.FindForm().ActiveControl = this; 17 this.FindForm().ActiveControl = item; 18 if (m_selectRow != null) 19 { 20 if (m_selectRow == item) 21 return; 22 m_selectRow.SetSelect(false); 23 } 24 m_selectRow = item as IDataGridViewRow; 25 m_selectRow.SetSelect(true); 26 if (ItemClick != null) 27 { 28 ItemClick(item, e); 29 } 30 if (this.panRow.Controls.Count > 0) 31 { 32 if (item.Location.Y < 0) 33 { 34 this.panRow.AutoScrollPosition = new Point(0, Math.Abs(this.panRow.Controls[this.panRow.Controls.Count - 1].Location.Y) + item.Location.Y); 35 } 36 else if (item.Location.Y + m_rowHeight > this.panRow.Height) 37 { 38 this.panRow.AutoScrollPosition = new Point(0, Math.Abs(this.panRow.AutoScrollPosition.Y) + item.Location.Y - this.panRow.Height + m_rowHeight); 39 } 40 } 41 } 42 finally 43 { 44 ControlHelper.FreezeControl(this, false); 45 } 46 } 47 private void UCDataGridView_Resize(object sender, EventArgs e) 48 { 49 ResetShowCount(); 50 ReloadSource(); 51 } 52 #endregion
对外公开的函数
1 #region 公共函数 2 /// <summary> 3 /// 刷新数据 4 /// </summary> 5 public void ReloadSource() 6 { 7 if (DesignMode) 8 { return; } 9 try 10 { 11 if (m_columns == null || m_columns.Count <= 0) 12 return; 13 14 ControlHelper.FreezeControl(this.panRow, true); 15 this.panRow.Controls.Clear(); 16 Rows = new List<IDataGridViewRow>(); 17 if (m_dataSource != null) 18 { 19 int intIndex = 0; 20 Control lastItem = null; 21 22 int intSourceCount = 0; 23 if (m_dataSource is DataTable) 24 { 25 intSourceCount = (m_dataSource as DataTable).Rows.Count; 26 } 27 else if (typeof(IList).IsAssignableFrom(m_dataSource.GetType())) 28 { 29 intSourceCount = (m_dataSource as IList).Count; 30 } 31 32 foreach (Control item in this.panRow.Controls) 33 { 34 35 36 if (intIndex >= intSourceCount) 37 { 38 item.Visible = false; 39 } 40 else 41 { 42 var row = (item as IDataGridViewRow); 43 row.IsShowCheckBox = m_isShowCheckBox; 44 if (m_dataSource is DataTable) 45 { 46 row.DataSource = (m_dataSource as DataTable).Rows[intIndex]; 47 } 48 else 49 { 50 row.DataSource = (m_dataSource as IList)[intIndex]; 51 } 52 row.BindingCellData(); 53 item.Height = m_rowHeight; 54 item.Visible = true; 55 item.BringToFront(); 56 if (lastItem == null) 57 lastItem = item; 58 Rows.Add(row); 59 } 60 intIndex++; 61 } 62 63 if (intIndex < intSourceCount) 64 { 65 for (int i = intIndex; i < intSourceCount; i++) 66 { 67 IDataGridViewRow row = (IDataGridViewRow)Activator.CreateInstance(m_rowType); 68 if (m_dataSource is DataTable) 69 { 70 row.DataSource = (m_dataSource as DataTable).Rows[i]; 71 } 72 else 73 { 74 row.DataSource = (m_dataSource as IList)[i]; 75 } 76 row.Columns = m_columns; 77 List<Control> lstCells = new List<Control>(); 78 row.IsShowCheckBox = m_isShowCheckBox; 79 row.ReloadCells(); 80 row.BindingCellData(); 81 82 83 Control rowControl = (row as Control); 84 rowControl.Height = m_rowHeight; 85 this.panRow.Controls.Add(rowControl); 86 rowControl.Dock = DockStyle.Top; 87 row.CellClick += (a, b) => { SetSelectRow(rowControl, b); }; 88 row.CheckBoxChangeEvent += (a, b) => { SetSelectRow(rowControl, b); }; 89 row.SourceChanged += RowSourceChanged; 90 rowControl.BringToFront(); 91 Rows.Add(row); 92 93 if (lastItem == null) 94 lastItem = rowControl; 95 } 96 } 97 if (lastItem != null && intSourceCount == m_showCount) 98 { 99 lastItem.Height = this.panRow.Height - (m_showCount - 1) * m_rowHeight; 100 } 101 } 102 } 103 finally 104 { 105 ControlHelper.FreezeControl(this.panRow, false); 106 } 107 } 108 109 110 /// <summary> 111 /// 快捷键 112 /// </summary> 113 /// <param name="msg"></param> 114 /// <param name="keyData"></param> 115 /// <returns></returns> 116 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 117 { 118 if (keyData == Keys.Up) 119 { 120 Previous(); 121 } 122 else if (keyData == Keys.Down) 123 { 124 Next(); 125 } 126 else if (keyData == Keys.Home) 127 { 128 First(); 129 } 130 else if (keyData == Keys.End) 131 { 132 End(); 133 } 134 return base.ProcessCmdKey(ref msg, keyData); 135 } 136 /// <summary> 137 /// 选中第一个 138 /// </summary> 139 public void First() 140 { 141 if (Rows == null || Rows.Count <= 0) 142 return; 143 Control c = null; 144 c = (Rows[0] as Control); 145 SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = 0 }); 146 } 147 /// <summary> 148 /// 选中上一个 149 /// </summary> 150 public void Previous() 151 { 152 if (Rows == null || Rows.Count <= 0) 153 return; 154 Control c = null; 155 156 int index = Rows.IndexOf(m_selectRow); 157 if (index - 1 >= 0) 158 { 159 c = (Rows[index - 1] as Control); 160 SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index - 1 }); 161 } 162 } 163 /// <summary> 164 /// 选中下一个 165 /// </summary> 166 public void Next() 167 { 168 if (Rows == null || Rows.Count <= 0) 169 return; 170 Control c = null; 171 172 int index = Rows.IndexOf(m_selectRow); 173 if (index + 1 < Rows.Count) 174 { 175 c = (Rows[index + 1] as Control); 176 SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index + 1 }); 177 } 178 } 179 /// <summary> 180 /// 选中最后一个 181 /// </summary> 182 public void End() 183 { 184 if (Rows == null || Rows.Count <= 0) 185 return; 186 Control c = null; 187 c = (Rows[Rows.Count - 1] as Control); 188 SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = Rows.Count - 1 }); 189 } 190 191 #endregion
完整代码
1 // 版权所有 黄正辉 交流群:568015492 QQ:623128629 2 // 文件名称:UCDataGridView.cs 3 // 创建日期:2019-08-15 15:59:25 4 // 功能描述:DataGridView 5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 6 using System; 7 using System.Collections.Generic; 8 using System.ComponentModel; 9 using System.Drawing; 10 using System.Data; 11 using System.Linq; 12 using System.Text; 13 using System.Windows.Forms; 14 using System.Collections; 15 16 namespace HZH_Controls.Controls 17 { 18 public partial class UCDataGridView : UserControl 19 { 20 #region 属性 21 private Font m_headFont = new Font("微软雅黑", 12F); 22 /// <summary> 23 /// 标题字体 24 /// </summary> 25 [Description("标题字体"), Category("自定义")] 26 public Font HeadFont 27 { 28 get { return m_headFont; } 29 set { m_headFont = value; } 30 } 31 private Color m_headTextColor = Color.Black; 32 /// <summary> 33 /// 标题字体颜色 34 /// </summary> 35 [Description("标题文字颜色"), Category("自定义")] 36 public Color HeadTextColor 37 { 38 get { return m_headTextColor; } 39 set { m_headTextColor = value; } 40 } 41 42 private bool m_isShowHead = true; 43 /// <summary> 44 /// 是否显示标题 45 /// </summary> 46 [Description("是否显示标题"), Category("自定义")] 47 public bool IsShowHead 48 { 49 get { return m_isShowHead; } 50 set 51 { 52 m_isShowHead = value; 53 panHead.Visible = value; 54 if (m_page != null) 55 { 56 ResetShowCount(); 57 m_page.PageSize = m_showCount; 58 } 59 } 60 } 61 private int m_headHeight = 40; 62 /// <summary> 63 /// 标题高度 64 /// </summary> 65 [Description("标题高度"), Category("自定义")] 66 public int HeadHeight 67 { 68 get { return m_headHeight; } 69 set 70 { 71 m_headHeight = value; 72 panHead.Height = value; 73 } 74 } 75 76 private bool m_isShowCheckBox = false; 77 /// <summary> 78 /// 是否显示复选框 79 /// </summary> 80 [Description("是否显示选择框"), Category("自定义")] 81 public bool IsShowCheckBox 82 { 83 get { return m_isShowCheckBox; } 84 set 85 { 86 if (value != m_isShowCheckBox) 87 { 88 m_isShowCheckBox = value; 89 LoadColumns(); 90 } 91 } 92 } 93 94 private int m_rowHeight = 40; 95 /// <summary> 96 /// 行高 97 /// </summary> 98 [Description("数据行高"), Category("自定义")] 99 public int RowHeight 100 { 101 get { return m_rowHeight; } 102 set { m_rowHeight = value; } 103 } 104 105 private int m_showCount = 0; 106 /// <summary> 107 /// 108 /// </summary> 109 [Description("可显示个数"), Category("自定义")] 110 public int ShowCount 111 { 112 get { return m_showCount; } 113 private set 114 { 115 m_showCount = value; 116 if (m_page != null) 117 { 118 m_page.PageSize = value; 119 } 120 } 121 } 122 123 private List<DataGridViewColumnEntity> m_columns; 124 /// <summary> 125 /// 列 126 /// </summary> 127 [Description("列"), Category("自定义")] 128 public List<DataGridViewColumnEntity> Columns 129 { 130 get { return m_columns; } 131 set 132 { 133 m_columns = value; 134 LoadColumns(); 135 } 136 } 137 138 private object m_dataSource; 139 /// <summary> 140 /// 数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource 141 /// </summary> 142 [Description("数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource"), Category("自定义")] 143 public object DataSource 144 { 145 get { return m_dataSource; } 146 set 147 { 148 if (value == null) 149 return; 150 if (!(m_dataSource is DataTable) && (!typeof(IList).IsAssignableFrom(value.GetType()))) 151 { 152 throw new Exception("数据源不是有效的数据类型,请使用Datatable或列表"); 153 } 154 155 m_dataSource = value; 156 ReloadSource(); 157 } 158 } 159 160 public List<IDataGridViewRow> Rows { get; private set; } 161 162 private Type m_rowType = typeof(UCDataGridViewRow); 163 /// <summary> 164 /// 行元素类型,默认UCDataGridViewItem 165 /// </summary> 166 [Description("行控件类型,默认UCDataGridViewRow,如果不满足请自定义行控件实现接口IDataGridViewRow"), Category("自定义")] 167 public Type RowType 168 { 169 get { return m_rowType; } 170 set 171 { 172 if (value == null) 173 return; 174 if (!typeof(IDataGridViewRow).IsAssignableFrom(value) || !value.IsSubclassOf(typeof(Control))) 175 throw new Exception("行控件没有实现IDataGridViewRow接口"); 176 m_rowType = value; 177 } 178 } 179 IDataGridViewRow m_selectRow = null; 180 /// <summary> 181 /// 选中的节点 182 /// </summary> 183 [Description("选中行"), Category("自定义")] 184 public IDataGridViewRow SelectRow 185 { 186 get { return m_selectRow; } 187 private set { m_selectRow = value; } 188 } 189 190 191 /// <summary> 192 /// 选中的行,如果显示CheckBox,则以CheckBox选中为准 193 /// </summary> 194 [Description("选中的行,如果显示CheckBox,则以CheckBox选中为准"), Category("自定义")] 195 public List<IDataGridViewRow> SelectRows 196 { 197 get 198 { 199 if (m_isShowCheckBox) 200 { 201 return Rows.FindAll(p => p.IsChecked); 202 } 203 else 204 return new List<IDataGridViewRow>() { m_selectRow }; 205 } 206 } 207 208 209 private UCPagerControlBase m_page = null; 210 /// <summary> 211 /// 翻页控件 212 /// </summary> 213 [Description("翻页控件,如果UCPagerControl不满足你的需求,请自定义翻页控件并继承UCPagerControlBase"), Category("自定义")] 214 public UCPagerControlBase Page 215 { 216 get { return m_page; } 217 set 218 { 219 m_page = value; 220 if (value != null) 221 { 222 if (!typeof(IPageControl).IsAssignableFrom(value.GetType()) || !value.GetType().IsSubclassOf(typeof(UCPagerControlBase))) 223 throw new Exception("翻页控件没有继承UCPagerControlBase"); 224 panPage.Visible = value != null; 225 m_page.ShowSourceChanged += page_ShowSourceChanged; 226 m_page.Dock = DockStyle.Fill; 227 this.panPage.Controls.Clear(); 228 this.panPage.Controls.Add(m_page); 229 ResetShowCount(); 230 m_page.PageSize = ShowCount; 231 this.DataSource = m_page.GetCurrentSource(); 232 } 233 else 234 { 235 m_page = null; 236 } 237 } 238 } 239 240 void page_ShowSourceChanged(object currentSource) 241 { 242 this.DataSource = currentSource; 243 } 244 245 #region 事件 246 [Description("选中标题选择框事件"), Category("自定义")] 247 public EventHandler HeadCheckBoxChangeEvent; 248 [Description("标题点击事件"), Category("自定义")] 249 public EventHandler HeadColumnClickEvent; 250 [Description("项点击事件"), Category("自定义")] 251 public event DataGridViewEventHandler ItemClick; 252 [Description("数据源改变事件"), Category("自定义")] 253 public event DataGridViewEventHandler SourceChanged; 254 #endregion 255 #endregion 256 257 public UCDataGridView() 258 { 259 InitializeComponent(); 260 } 261 262 #region 私有方法 263 #region 加载column 264 /// <summary> 265 /// 功能描述:加载column 266 /// 作 者:HZH 267 /// 创建日期:2019-08-08 17:51:50 268 /// 任务编号:POS 269 /// </summary> 270 private void LoadColumns() 271 { 272 try 273 { 274 if (DesignMode) 275 { return; } 276 277 ControlHelper.FreezeControl(this.panHead, true); 278 this.panColumns.Controls.Clear(); 279 this.panColumns.ColumnStyles.Clear(); 280 281 if (m_columns != null && m_columns.Count() > 0) 282 { 283 int intColumnsCount = m_columns.Count(); 284 if (m_isShowCheckBox) 285 { 286 intColumnsCount++; 287 } 288 this.panColumns.ColumnCount = intColumnsCount; 289 for (int i = 0; i < intColumnsCount; i++) 290 { 291 Control c = null; 292 if (i == 0 && m_isShowCheckBox) 293 { 294 this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Absolute, 30F)); 295 296 UCCheckBox box = new UCCheckBox(); 297 box.TextValue = ""; 298 box.Size = new Size(30, 30); 299 box.CheckedChangeEvent += (a, b) => 300 { 301 Rows.ForEach(p => p.IsChecked = box.Checked); 302 if (HeadCheckBoxChangeEvent != null) 303 { 304 HeadCheckBoxChangeEvent(a, b); 305 } 306 }; 307 c = box; 308 } 309 else 310 { 311 var item = m_columns[i - (m_isShowCheckBox ? 1 : 0)]; 312 this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width)); 313 Label lbl = new Label(); 314 lbl.Name = "dgvColumns_" + i; 315 lbl.Text = item.HeadText; 316 lbl.Font = m_headFont; 317 lbl.ForeColor = m_headTextColor; 318 lbl.TextAlign = ContentAlignment.MiddleCenter; 319 lbl.AutoSize = false; 320 lbl.Dock = DockStyle.Fill; 321 lbl.MouseDown += (a, b) => 322 { 323 if (HeadColumnClickEvent != null) 324 { 325 HeadColumnClickEvent(a, b); 326 } 327 }; 328 c = lbl; 329 } 330 this.panColumns.Controls.Add(c, i, 0); 331 } 332 333 } 334 } 335 finally 336 { 337 ControlHelper.FreezeControl(this.panHead, false); 338 } 339 } 340 #endregion 341 342 /// <summary> 343 /// 功能描述:获取显示个数 344 /// 作 者:HZH 345 /// 创建日期:2019-03-05 10:02:58 346 /// 任务编号:POS 347 /// </summary> 348 /// <returns>返回值</returns> 349 private void ResetShowCount() 350 { 351 if (DesignMode) 352 { return; } 353 ShowCount = this.panRow.Height / (m_rowHeight); 354 int intCha = this.panRow.Height % (m_rowHeight); 355 m_rowHeight += intCha / ShowCount; 356 } 357 #endregion 358 359 #region 公共函数 360 /// <summary> 361 /// 刷新数据 362 /// </summary> 363 public void ReloadSource() 364 { 365 if (DesignMode) 366 { return; } 367 try 368 { 369 if (m_columns == null || m_columns.Count <= 0) 370 return; 371 372 ControlHelper.FreezeControl(this.panRow, true); 373 this.panRow.Controls.Clear(); 374 Rows = new List<IDataGridViewRow>(); 375 if (m_dataSource != null) 376 { 377 int intIndex = 0; 378 Control lastItem = null; 379 380 int intSourceCount = 0; 381 if (m_dataSource is DataTable) 382 { 383 intSourceCount = (m_dataSource as DataTable).Rows.Count; 384 } 385 else if (typeof(IList).IsAssignableFrom(m_dataSource.GetType())) 386 { 387 intSourceCount = (m_dataSource as IList).Count; 388 } 389 390 foreach (Control item in this.panRow.Controls) 391 { 392 393 394 if (intIndex >= intSourceCount) 395 { 396 item.Visible = false; 397 } 398 else 399 { 400 var row = (item as IDataGridViewRow); 401 row.IsShowCheckBox = m_isShowCheckBox; 402 if (m_dataSource is DataTable) 403 { 404 row.DataSource = (m_dataSource as DataTable).Rows[intIndex]; 405 } 406 else 407 { 408 row.DataSource = (m_dataSource as IList)[intIndex]; 409 } 410 row.BindingCellData(); 411 item.Height = m_rowHeight; 412 item.Visible = true; 413 item.BringToFront(); 414 if (lastItem == null) 415 lastItem = item; 416 Rows.Add(row); 417 } 418 intIndex++; 419 } 420 421 if (intIndex < intSourceCount) 422 { 423 for (int i = intIndex; i < intSourceCount; i++) 424 { 425 IDataGridViewRow row = (IDataGridViewRow)Activator.CreateInstance(m_rowType); 426 if (m_dataSource is DataTable) 427 { 428 row.DataSource = (m_dataSource as DataTable).Rows[i]; 429 } 430 else 431 { 432 row.DataSource = (m_dataSource as IList)[i]; 433 } 434 row.Columns = m_columns; 435 List<Control> lstCells = new List<Control>(); 436 row.IsShowCheckBox = m_isShowCheckBox; 437 row.ReloadCells(); 438 row.BindingCellData(); 439 440 441 Control rowControl = (row as Control); 442 rowControl.Height = m_rowHeight; 443 this.panRow.Controls.Add(rowControl); 444 rowControl.Dock = DockStyle.Top; 445 row.CellClick += (a, b) => { SetSelectRow(rowControl, b); }; 446 row.CheckBoxChangeEvent += (a, b) => { SetSelectRow(rowControl, b); }; 447 row.SourceChanged += RowSourceChanged; 448 rowControl.BringToFront(); 449 Rows.Add(row); 450 451 if (lastItem == null) 452 lastItem = rowControl; 453 } 454 } 455 if (lastItem != null && intSourceCount == m_showCount) 456 { 457 lastItem.Height = this.panRow.Height - (m_showCount - 1) * m_rowHeight; 458 } 459 } 460 } 461 finally 462 { 463 ControlHelper.FreezeControl(this.panRow, false); 464 } 465 } 466 467 468 /// <summary> 469 /// 快捷键 470 /// </summary> 471 /// <param name="msg"></param> 472 /// <param name="keyData"></param> 473 /// <returns></returns> 474 protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 475 { 476 if (keyData == Keys.Up) 477 { 478 Previous(); 479 } 480 else if (keyData == Keys.Down) 481 { 482 Next(); 483 } 484 else if (keyData == Keys.Home) 485 { 486 First(); 487 } 488 else if (keyData == Keys.End) 489 { 490 End(); 491 } 492 return base.ProcessCmdKey(ref msg, keyData); 493 } 494 /// <summary> 495 /// 选中第一个 496 /// </summary> 497 public void First() 498 { 499 if (Rows == null || Rows.Count <= 0) 500 return; 501 Control c = null; 502 c = (Rows[0] as Control); 503 SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = 0 }); 504 } 505 /// <summary> 506 /// 选中上一个 507 /// </summary> 508 public void Previous() 509 { 510 if (Rows == null || Rows.Count <= 0) 511 return; 512 Control c = null; 513 514 int index = Rows.IndexOf(m_selectRow); 515 if (index - 1 >= 0) 516 { 517 c = (Rows[index - 1] as Control); 518 SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index - 1 }); 519 } 520 } 521 /// <summary> 522 /// 选中下一个 523 /// </summary> 524 public void Next() 525 { 526 if (Rows == null || Rows.Count <= 0) 527 return; 528 Control c = null; 529 530 int index = Rows.IndexOf(m_selectRow); 531 if (index + 1 < Rows.Count) 532 { 533 c = (Rows[index + 1] as Control); 534 SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index + 1 }); 535 } 536 } 537 /// <summary> 538 /// 选中最后一个 539 /// </summary> 540 public void End() 541 { 542 if (Rows == null || Rows.Count <= 0) 543 return; 544 Control c = null; 545 c = (Rows[Rows.Count - 1] as Control); 546 SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = Rows.Count - 1 }); 547 } 548 549 #endregion 550 551 #region 事件 552 void RowSourceChanged(object sender, DataGridViewEventArgs e) 553 { 554 if (SourceChanged != null) 555 SourceChanged(sender, e); 556 } 557 private void SetSelectRow(Control item, DataGridViewEventArgs e) 558 { 559 try 560 { 561 ControlHelper.FreezeControl(this, true); 562 if (item == null) 563 return; 564 if (item.Visible == false) 565 return; 566 this.FindForm().ActiveControl = this; 567 this.FindForm().ActiveControl = item; 568 if (m_selectRow != null) 569 { 570 if (m_selectRow == item) 571 return; 572 m_selectRow.SetSelect(false); 573 } 574 m_selectRow = item as IDataGridViewRow; 575 m_selectRow.SetSelect(true); 576 if (ItemClick != null) 577 { 578 ItemClick(item, e); 579 } 580 if (this.panRow.Controls.Count > 0) 581 { 582 if (item.Location.Y < 0) 583 { 584 this.panRow.AutoScrollPosition = new Point(0, Math.Abs(this.panRow.Controls[this.panRow.Controls.Count - 1].Location.Y) + item.Location.Y); 585 } 586 else if (item.Location.Y + m_rowHeight > this.panRow.Height) 587 { 588 this.panRow.AutoScrollPosition = new Point(0, Math.Abs(this.panRow.AutoScrollPosition.Y) + item.Location.Y - this.panRow.Height + m_rowHeight); 589 } 590 } 591 } 592 finally 593 { 594 ControlHelper.FreezeControl(this, false); 595 } 596 } 597 private void UCDataGridView_Resize(object sender, EventArgs e) 598 { 599 ResetShowCount(); 600 ReloadSource(); 601 } 602 #endregion 603 } 604 }
1 namespace HZH_Controls.Controls 2 { 3 partial class UCDataGridView 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.panHead = new System.Windows.Forms.Panel(); 32 this.panColumns = new System.Windows.Forms.TableLayoutPanel(); 33 this.ucSplitLine_H1 = new HZH_Controls.Controls.UCSplitLine_H(); 34 this.panRow = new System.Windows.Forms.Panel(); 35 this.panPage = new System.Windows.Forms.Panel(); 36 this.panHead.SuspendLayout(); 37 this.SuspendLayout(); 38 // 39 // panHead 40 // 41 this.panHead.Controls.Add(this.panColumns); 42 this.panHead.Controls.Add(this.ucSplitLine_H1); 43 this.panHead.Dock = System.Windows.Forms.DockStyle.Top; 44 this.panHead.Location = new System.Drawing.Point(0, 0); 45 this.panHead.Name = "panHead"; 46 this.panHead.Size = new System.Drawing.Size(1061, 40); 47 this.panHead.TabIndex = 0; 48 // 49 // panColumns 50 // 51 this.panColumns.ColumnCount = 1; 52 this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); 53 this.panColumns.Dock = System.Windows.Forms.DockStyle.Fill; 54 this.panColumns.Location = new System.Drawing.Point(0, 0); 55 this.panColumns.Name = "panColumns"; 56 this.panColumns.RowCount = 1; 57 this.panColumns.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); 58 this.panColumns.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); 59 this.panColumns.Size = new System.Drawing.Size(1061, 39); 60 this.panColumns.TabIndex = 1; 61 // 62 // ucSplitLine_H1 63 // 64 this.ucSplitLine_H1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232))))); 65 this.ucSplitLine_H1.Dock = System.Windows.Forms.DockStyle.Bottom; 66 this.ucSplitLine_H1.Location = new System.Drawing.Point(0, 39); 67 this.ucSplitLine_H1.Name = "ucSplitLine_H1"; 68 this.ucSplitLine_H1.Size = new System.Drawing.Size(1061, 1); 69 this.ucSplitLine_H1.TabIndex = 0; 70 this.ucSplitLine_H1.TabStop = false; 71 // 72 // panRow 73 // 74 this.panRow.AutoScroll = true; 75 this.panRow.Dock = System.Windows.Forms.DockStyle.Fill; 76 this.panRow.Location = new System.Drawing.Point(0, 40); 77 this.panRow.Name = "panRow"; 78 this.panRow.Size = new System.Drawing.Size(1061, 475); 79 this.panRow.TabIndex = 1; 80 // 81 // panPage 82 // 83 this.panPage.Dock = System.Windows.Forms.DockStyle.Bottom; 84 this.panPage.Location = new System.Drawing.Point(0, 515); 85 this.panPage.Name = "panPage"; 86 this.panPage.Size = new System.Drawing.Size(1061, 50); 87 this.panPage.TabIndex = 0; 88 this.panPage.Visible = false; 89 // 90 // UCDataGridView 91 // 92 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; 93 this.BackColor = System.Drawing.Color.White; 94 this.Controls.Add(this.panRow); 95 this.Controls.Add(this.panPage); 96 this.Controls.Add(this.panHead); 97 this.Name = "UCDataGridView"; 98 this.Size = new System.Drawing.Size(1061, 565); 99 this.Resize += new System.EventHandler(this.UCDataGridView_Resize); 100 this.panHead.ResumeLayout(false); 101 this.ResumeLayout(false); 102 103 } 104 105 #endregion 106 107 private System.Windows.Forms.Panel panHead; 108 private System.Windows.Forms.TableLayoutPanel panColumns; 109 private UCSplitLine_H ucSplitLine_H1; 110 private System.Windows.Forms.Panel panRow; 111 private System.Windows.Forms.Panel panPage; 112 113 } 114 }
如果你仔细看,你会发现行我用了类型进行传入,当你需要更丰富的行内容的时候,可以自定义行控件,然后通过RowType属性传入
分页控件我使用了分页控件基类UCPagerControlBase,这样做的好处就是你同样可以扩展分页控件
用处及效果
调用示例
1 List<DataGridViewColumnEntity> lstCulumns = new List<DataGridViewColumnEntity>(); 2 lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "ID", HeadText = "编号", Width = 70, WidthType = SizeType.Absolute }); 3 lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "Name", HeadText = "姓名", Width = 50, WidthType = SizeType.Percent }); 4 lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "Age", HeadText = "年龄", Width = 50, WidthType = SizeType.Percent }); 5 lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "Birthday", HeadText = "生日", Width = 50, WidthType = SizeType.Percent, Format = (a) => { return ((DateTime)a).ToString("yyyy-MM-dd"); } }); 6 lstCulumns.Add(new DataGridViewColumnEntity() { DataField = "Sex", HeadText = "性别", Width = 50, WidthType = SizeType.Percent, Format = (a) => { return ((int)a) == 0 ? "女" : "男"; } }); 7 this.ucDataGridView1.Columns = lstCulumns; 8 this.ucDataGridView1.IsShowCheckBox = true; 9 List<object> lstSource = new List<object>(); 10 for (int i = 0; i < 200; i++) 11 { 12 TestModel model = new TestModel() 13 { 14 ID = i.ToString(), 15 Age = 3 * i, 16 Name = "姓名——" + i, 17 Birthday = DateTime.Now.AddYears(-10), 18 Sex = i % 2 19 }; 20 lstSource.Add(model); 21 } 22 23 var page = new UCPagerControl2(); 24 page.DataSource = lstSource; 25 this.ucDataGridView1.Page = page; 26 this.ucDataGridView1.First();
如果使用分页控件,则将数据源指定给分页控件,否则直接指定给表格控件数据源
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧