-
2021-12-25 01:35:59
数据表格控件是WinForm窗体应用程序中用于查询时以表格形式显示数据的重要控件,我们搞工控上位机也经常需要用到报表日志或者其他信息的记录,这篇文章讲讲如何给控件快速绑定数据源,将你的实体属性类直接赋到控件中。
(1)先建立一个实体类,拉出datagridview控件,点击右上角一个三角形,选择添加项目源,选上刚刚建立的Students的类,确认完成。
(2)确认后会出自动出现一个标题列,就是刚刚绑定类里面的三个属性,选择编辑列,这里可以更改列的标题文本,比如Name改成姓名(3)最后是加入数据,先实例化一个students类的集合,将集合自己赋值给datagridview的数据源,数据就会出现在表格中了,如下图。
代码展示:using System; using System.Collections.Generic; using System.Windows.Forms; namespace DataGridView绑定类对象 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { List<Students> students = new List<Students>(); students.Add(new Students { Name="李增光",Age=18,Sex="男"}); //直接将这个学生对象的集合设置为Datagridview的数据源 dataGridView1.DataSource = students; } } public class Students { public string Name { get; set; } public int Age { get; set; } public string Sex { get; set; } } }
本文案例的源码放在下面的链接中,需要可以自取。
链接:https://pan.baidu.com/s/1Qjc8Cal9STbqEtVPJ_ywwQ
提取码:7fxt更多相关内容 -
WinForm下的表格控件ReoGrid2.0使用示例 开源免费表格控件
2018-10-25 16:43:52ReoGrid .NET Spreadsheet Component C# 和 VB.net 开源免费的表格控件, 界面很漂亮, 功能很强大 其它的自己搜一下吧,当前版本是2.0的使用示例 -
微软自带winform图表控件样例大全开源免费
2020-10-07 15:16:43微软自带winform图表控件样例大全开源免费,饼状图,雷达图,折线图,柱状图,实时曲线图等等,附件为微软的工具库自带的Chart图表的简单应用 -
winform表格分页控件
2018-12-04 09:35:34支持各种表格控件分页,可自行修改不同的分页方式。。 -
(三十二)c#Winform自定义控件-表格
2019-09-08 10:35:28入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git 如果...前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
目录
https://blog.csdn.net/kwwwvagaa/article/details/100586547
准备工作
表格控件将拆分为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 }
完整的代码
View Code
View Code
接下来就是列表控件了
添加一个用户控件,命名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
完整代码
// 版权所有 黄正辉 交流群:568015492 QQ:623128629 // 文件名称:UCDataGridView.cs // 创建日期:2019-08-15 15:59:25 // 功能描述:DataGridView // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Windows.Forms; using System.Collections; namespace HZH_Controls.Controls { public partial class UCDataGridView : UserControl { #region 属性 private Font m_headFont = new Font("微软雅黑", 12F); /// <summary> /// 标题字体 /// </summary> [Description("标题字体"), Category("自定义")] public Font HeadFont { get { return m_headFont; } set { m_headFont = value; } } private Color m_headTextColor = Color.Black; /// <summary> /// 标题字体颜色 /// </summary> [Description("标题文字颜色"), Category("自定义")] public Color HeadTextColor { get { return m_headTextColor; } set { m_headTextColor = value; } } private bool m_isShowHead = true; /// <summary> /// 是否显示标题 /// </summary> [Description("是否显示标题"), Category("自定义")] public bool IsShowHead { get { return m_isShowHead; } set { m_isShowHead = value; panHead.Visible = value; if (m_page != null) { ResetShowCount(); m_page.PageSize = m_showCount; } } } private int m_headHeight = 40; /// <summary> /// 标题高度 /// </summary> [Description("标题高度"), Category("自定义")] public int HeadHeight { get { return m_headHeight; } set { m_headHeight = value; panHead.Height = value; } } private bool m_isShowCheckBox = false; /// <summary> /// 是否显示复选框 /// </summary> [Description("是否显示选择框"), Category("自定义")] public bool IsShowCheckBox { get { return m_isShowCheckBox; } set { if (value != m_isShowCheckBox) { m_isShowCheckBox = value; LoadColumns(); } } } private int m_rowHeight = 40; /// <summary> /// 行高 /// </summary> [Description("数据行高"), Category("自定义")] public int RowHeight { get { return m_rowHeight; } set { m_rowHeight = value; } } private int m_showCount = 0; /// <summary> /// /// </summary> [Description("可显示个数"), Category("自定义")] public int ShowCount { get { return m_showCount; } private set { m_showCount = value; if (m_page != null) { m_page.PageSize = value; } } } private List<DataGridViewColumnEntity> m_columns; /// <summary> /// 列 /// </summary> [Description("列"), Category("自定义")] public List<DataGridViewColumnEntity> Columns { get { return m_columns; } set { m_columns = value; LoadColumns(); } } private object m_dataSource; /// <summary> /// 数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource /// </summary> [Description("数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的DataSource"), Category("自定义")] public object DataSource { get { return m_dataSource; } set { if (value == null) return; if (!(m_dataSource is DataTable) && (!typeof(IList).IsAssignableFrom(value.GetType()))) { throw new Exception("数据源不是有效的数据类型,请使用Datatable或列表"); } m_dataSource = value; ReloadSource(); } } public List<IDataGridViewRow> Rows { get; private set; } private Type m_rowType = typeof(UCDataGridViewRow); /// <summary> /// 行元素类型,默认UCDataGridViewItem /// </summary> [Description("行控件类型,默认UCDataGridViewRow,如果不满足请自定义行控件实现接口IDataGridViewRow"), Category("自定义")] public Type RowType { get { return m_rowType; } set { if (value == null) return; if (!typeof(IDataGridViewRow).IsAssignableFrom(value) || !value.IsSubclassOf(typeof(Control))) throw new Exception("行控件没有实现IDataGridViewRow接口"); m_rowType = value; } } IDataGridViewRow m_selectRow = null; /// <summary> /// 选中的节点 /// </summary> [Description("选中行"), Category("自定义")] public IDataGridViewRow SelectRow { get { return m_selectRow; } private set { m_selectRow = value; } } /// <summary> /// 选中的行,如果显示CheckBox,则以CheckBox选中为准 /// </summary> [Description("选中的行,如果显示CheckBox,则以CheckBox选中为准"), Category("自定义")] public List<IDataGridViewRow> SelectRows { get { if (m_isShowCheckBox) { return Rows.FindAll(p => p.IsChecked); } else return new List<IDataGridViewRow>() { m_selectRow }; } } private UCPagerControlBase m_page = null; /// <summary> /// 翻页控件 /// </summary> [Description("翻页控件,如果UCPagerControl不满足你的需求,请自定义翻页控件并继承UCPagerControlBase"), Category("自定义")] public UCPagerControlBase Page { get { return m_page; } set { m_page = value; if (value != null) { if (!typeof(IPageControl).IsAssignableFrom(value.GetType()) || !value.GetType().IsSubclassOf(typeof(UCPagerControlBase))) throw new Exception("翻页控件没有继承UCPagerControlBase"); panPage.Visible = value != null; m_page.ShowSourceChanged += page_ShowSourceChanged; m_page.Dock = DockStyle.Fill; this.panPage.Controls.Clear(); this.panPage.Controls.Add(m_page); ResetShowCount(); m_page.PageSize = ShowCount; this.DataSource = m_page.GetCurrentSource(); } else { m_page = null; } } } void page_ShowSourceChanged(object currentSource) { this.DataSource = currentSource; } #region 事件 [Description("选中标题选择框事件"), Category("自定义")] public EventHandler HeadCheckBoxChangeEvent; [Description("标题点击事件"), Category("自定义")] public EventHandler HeadColumnClickEvent; [Description("项点击事件"), Category("自定义")] public event DataGridViewEventHandler ItemClick; [Description("数据源改变事件"), Category("自定义")] public event DataGridViewEventHandler SourceChanged; #endregion #endregion public UCDataGridView() { InitializeComponent(); } #region 私有方法 #region 加载column /// <summary> /// 功能描述:加载column /// 作 者:HZH /// 创建日期:2019-08-08 17:51:50 /// 任务编号:POS /// </summary> private void LoadColumns() { try { if (DesignMode) { return; } ControlHelper.FreezeControl(this.panHead, true); this.panColumns.Controls.Clear(); this.panColumns.ColumnStyles.Clear(); if (m_columns != null && m_columns.Count() > 0) { int intColumnsCount = m_columns.Count(); if (m_isShowCheckBox) { intColumnsCount++; } this.panColumns.ColumnCount = intColumnsCount; for (int i = 0; i < intColumnsCount; i++) { Control c = null; if (i == 0 && m_isShowCheckBox) { this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(SizeType.Absolute, 30F)); UCCheckBox box = new UCCheckBox(); box.TextValue = ""; box.Size = new Size(30, 30); box.CheckedChangeEvent += (a, b) => { Rows.ForEach(p => p.IsChecked = box.Checked); if (HeadCheckBoxChangeEvent != null) { HeadCheckBoxChangeEvent(a, b); } }; c = box; } else { var item = m_columns[i - (m_isShowCheckBox ? 1 : 0)]; this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(item.WidthType, item.Width)); Label lbl = new Label(); lbl.Name = "dgvColumns_" + i; lbl.Text = item.HeadText; lbl.Font = m_headFont; lbl.ForeColor = m_headTextColor; lbl.TextAlign = ContentAlignment.MiddleCenter; lbl.AutoSize = false; lbl.Dock = DockStyle.Fill; lbl.MouseDown += (a, b) => { if (HeadColumnClickEvent != null) { HeadColumnClickEvent(a, b); } }; c = lbl; } this.panColumns.Controls.Add(c, i, 0); } } } finally { ControlHelper.FreezeControl(this.panHead, false); } } #endregion /// <summary> /// 功能描述:获取显示个数 /// 作 者:HZH /// 创建日期:2019-03-05 10:02:58 /// 任务编号:POS /// </summary> /// <returns>返回值</returns> private void ResetShowCount() { if (DesignMode) { return; } ShowCount = this.panRow.Height / (m_rowHeight); int intCha = this.panRow.Height % (m_rowHeight); m_rowHeight += intCha / ShowCount; } #endregion #region 公共函数 /// <summary> /// 刷新数据 /// </summary> public void ReloadSource() { if (DesignMode) { return; } try { if (m_columns == null || m_columns.Count <= 0) return; ControlHelper.FreezeControl(this.panRow, true); this.panRow.Controls.Clear(); Rows = new List<IDataGridViewRow>(); if (m_dataSource != null) { int intIndex = 0; Control lastItem = null; int intSourceCount = 0; if (m_dataSource is DataTable) { intSourceCount = (m_dataSource as DataTable).Rows.Count; } else if (typeof(IList).IsAssignableFrom(m_dataSource.GetType())) { intSourceCount = (m_dataSource as IList).Count; } foreach (Control item in this.panRow.Controls) { if (intIndex >= intSourceCount) { item.Visible = false; } else { var row = (item as IDataGridViewRow); row.IsShowCheckBox = m_isShowCheckBox; if (m_dataSource is DataTable) { row.DataSource = (m_dataSource as DataTable).Rows[intIndex]; } else { row.DataSource = (m_dataSource as IList)[intIndex]; } row.BindingCellData(); item.Height = m_rowHeight; item.Visible = true; item.BringToFront(); if (lastItem == null) lastItem = item; Rows.Add(row); } intIndex++; } if (intIndex < intSourceCount) { for (int i = intIndex; i < intSourceCount; i++) { IDataGridViewRow row = (IDataGridViewRow)Activator.CreateInstance(m_rowType); if (m_dataSource is DataTable) { row.DataSource = (m_dataSource as DataTable).Rows[i]; } else { row.DataSource = (m_dataSource as IList)[i]; } row.Columns = m_columns; List<Control> lstCells = new List<Control>(); row.IsShowCheckBox = m_isShowCheckBox; row.ReloadCells(); row.BindingCellData(); Control rowControl = (row as Control); rowControl.Height = m_rowHeight; this.panRow.Controls.Add(rowControl); rowControl.Dock = DockStyle.Top; row.CellClick += (a, b) => { SetSelectRow(rowControl, b); }; row.CheckBoxChangeEvent += (a, b) => { SetSelectRow(rowControl, b); }; row.SourceChanged += RowSourceChanged; rowControl.BringToFront(); Rows.Add(row); if (lastItem == null) lastItem = rowControl; } } if (lastItem != null && intSourceCount == m_showCount) { lastItem.Height = this.panRow.Height - (m_showCount - 1) * m_rowHeight; } } } finally { ControlHelper.FreezeControl(this.panRow, false); } } /// <summary> /// 快捷键 /// </summary> /// <param name="msg"></param> /// <param name="keyData"></param> /// <returns></returns> protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if (keyData == Keys.Up) { Previous(); } else if (keyData == Keys.Down) { Next(); } else if (keyData == Keys.Home) { First(); } else if (keyData == Keys.End) { End(); } return base.ProcessCmdKey(ref msg, keyData); } /// <summary> /// 选中第一个 /// </summary> public void First() { if (Rows == null || Rows.Count <= 0) return; Control c = null; c = (Rows[0] as Control); SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = 0 }); } /// <summary> /// 选中上一个 /// </summary> public void Previous() { if (Rows == null || Rows.Count <= 0) return; Control c = null; int index = Rows.IndexOf(m_selectRow); if (index - 1 >= 0) { c = (Rows[index - 1] as Control); SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index - 1 }); } } /// <summary> /// 选中下一个 /// </summary> public void Next() { if (Rows == null || Rows.Count <= 0) return; Control c = null; int index = Rows.IndexOf(m_selectRow); if (index + 1 < Rows.Count) { c = (Rows[index + 1] as Control); SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = index + 1 }); } } /// <summary> /// 选中最后一个 /// </summary> public void End() { if (Rows == null || Rows.Count <= 0) return; Control c = null; c = (Rows[Rows.Count - 1] as Control); SetSelectRow(c, new DataGridViewEventArgs() { RowIndex = Rows.Count - 1 }); } #endregion #region 事件 void RowSourceChanged(object sender, DataGridViewEventArgs e) { if (SourceChanged != null) SourceChanged(sender, e); } private void SetSelectRow(Control item, DataGridViewEventArgs e) { try { ControlHelper.FreezeControl(this, true); if (item == null) return; if (item.Visible == false) return; this.FindForm().ActiveControl = this; this.FindForm().ActiveControl = item; if (m_selectRow != null) { if (m_selectRow == item) return; m_selectRow.SetSelect(false); } m_selectRow = item as IDataGridViewRow; m_selectRow.SetSelect(true); if (ItemClick != null) { ItemClick(item, e); } if (this.panRow.Controls.Count > 0) { if (item.Location.Y < 0) { this.panRow.AutoScrollPosition = new Point(0, Math.Abs(this.panRow.Controls[this.panRow.Controls.Count - 1].Location.Y) + item.Location.Y); } else if (item.Location.Y + m_rowHeight > this.panRow.Height) { this.panRow.AutoScrollPosition = new Point(0, Math.Abs(this.panRow.AutoScrollPosition.Y) + item.Location.Y - this.panRow.Height + m_rowHeight); } } } finally { ControlHelper.FreezeControl(this, false); } } private void UCDataGridView_Resize(object sender, EventArgs e) { ResetShowCount(); ReloadSource(); } #endregion } }
namespace HZH_Controls.Controls { partial class UCDataGridView { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// 清理所有正在使用的资源。 /// </summary> /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); } #region 组件设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要 /// 使用代码编辑器修改此方法的内容。 /// </summary> private void InitializeComponent() { this.panHead = new System.Windows.Forms.Panel(); this.panColumns = new System.Windows.Forms.TableLayoutPanel(); this.ucSplitLine_H1 = new HZH_Controls.Controls.UCSplitLine_H(); this.panRow = new System.Windows.Forms.Panel(); this.panPage = new System.Windows.Forms.Panel(); this.panHead.SuspendLayout(); this.SuspendLayout(); // // panHead // this.panHead.Controls.Add(this.panColumns); this.panHead.Controls.Add(this.ucSplitLine_H1); this.panHead.Dock = System.Windows.Forms.DockStyle.Top; this.panHead.Location = new System.Drawing.Point(0, 0); this.panHead.Name = "panHead"; this.panHead.Size = new System.Drawing.Size(1061, 40); this.panHead.TabIndex = 0; // // panColumns // this.panColumns.ColumnCount = 1; this.panColumns.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.panColumns.Dock = System.Windows.Forms.DockStyle.Fill; this.panColumns.Location = new System.Drawing.Point(0, 0); this.panColumns.Name = "panColumns"; this.panColumns.RowCount = 1; this.panColumns.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F)); this.panColumns.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F)); this.panColumns.Size = new System.Drawing.Size(1061, 39); this.panColumns.TabIndex = 1; // // ucSplitLine_H1 // this.ucSplitLine_H1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232))))); this.ucSplitLine_H1.Dock = System.Windows.Forms.DockStyle.Bottom; this.ucSplitLine_H1.Location = new System.Drawing.Point(0, 39); this.ucSplitLine_H1.Name = "ucSplitLine_H1"; this.ucSplitLine_H1.Size = new System.Drawing.Size(1061, 1); this.ucSplitLine_H1.TabIndex = 0; this.ucSplitLine_H1.TabStop = false; // // panRow // this.panRow.AutoScroll = true; this.panRow.Dock = System.Windows.Forms.DockStyle.Fill; this.panRow.Location = new System.Drawing.Point(0, 40); this.panRow.Name = "panRow"; this.panRow.Size = new System.Drawing.Size(1061, 475); this.panRow.TabIndex = 1; // // panPage // this.panPage.Dock = System.Windows.Forms.DockStyle.Bottom; this.panPage.Location = new System.Drawing.Point(0, 515); this.panPage.Name = "panPage"; this.panPage.Size = new System.Drawing.Size(1061, 50); this.panPage.TabIndex = 0; this.panPage.Visible = false; // // UCDataGridView // this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None; this.BackColor = System.Drawing.Color.White; this.Controls.Add(this.panRow); this.Controls.Add(this.panPage); this.Controls.Add(this.panHead); this.Name = "UCDataGridView"; this.Size = new System.Drawing.Size(1061, 565); this.Resize += new System.EventHandler(this.UCDataGridView_Resize); this.panHead.ResumeLayout(false); this.ResumeLayout(false); } #endregion private System.Windows.Forms.Panel panHead; private System.Windows.Forms.TableLayoutPanel panColumns; private UCSplitLine_H ucSplitLine_H1; private System.Windows.Forms.Panel panRow; private System.Windows.Forms.Panel panPage; } }
如果你仔细看,你会发现行我用了类型进行传入,当你需要更丰富的行内容的时候,可以自定义行控件,然后通过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 点个星 星吧
-
XPTable-winform很强大的表格控件
2008-11-06 16:53:55XPTable-winform很强大的表格控件,可以实现很多DATAGRIDVIEW没有的功能,如进度条,图片,下拉框等很多 -
C#--WinForm--表格数据控件DataGridView--绑定模式
2017-10-17 00:31:03官方文档DataGridView控件提供了一种强大而灵活的以表格形式显示数据的方式。用户可以使用DataGridView控件来显示少量数据的只读视图,也可以对其进行缩放以显示特大数据集的可编辑视图。扩展DataGridView控件有很多...DataGridView控件提供了一种强大而灵活的以表格形式显示数据的方式。用户可以使用DataGridView控件来显示少量数据的只读视图,也可以对其进行缩放以显示特大数据集的可编辑视图。
扩展DataGridView控件有很多方式
例如可以采用编程方式指定自己的排序算法来创建自己的单元格类型,通过选择一些属性,可以轻松的自定义DataDridView控件的外观:可以将许多类型的数据存储区用作数据源:也可以在没有绑定数据源的情况下操作DataGridView控件。
拖放Dgv控件
DataGridView绑定数据方法
俩种方法:
1:绑定模式
将已存在的数据库中数据表绑定到控件上
2:非绑定模式
通过代码手动填充数据
绑定模式
绑定本机上的数据库以SQLServer示例:
允许用户增加行:
允许用户删除行:
允许用户重置列:
允许用户调整列大小:
允许用户调整行大小:
可见列大小调整模式:
开发中一般选择AllCells模式,根据文字长度自适应
设置背景颜色:
网格线颜色:
用户不可手动编辑
-
C#Winform的DataGridView控件使用详解2—DataGridView表格样式设置及表格操作
2021-09-01 23:15:54C#Winform的DataGridView控件使用详解2—DataGridView表格样式设置及表格操作 实现DataGridView控件的表格样式设置、行号的显示、表格行的增减、表格内容的清除和DataGridView单元格与Excel表格的复制粘贴操作。C#Winform的DataGridView控件使用详解2—DataGridView表格样式设置及表格操作
在展示和处理二维数据时,我们常常会想起Excel。但是使用Excel自带的各种函数处理较为繁琐的步骤时显得略显吃力,如果使用Excel自带宏编程,可能会对VB语言不甚熟悉或是感觉不nice。这个时候,熟悉C#编程语言的你,就需要用到DataGridView控件,设计一款二维数据处理利器。 此处,我们开始进入对DataGridView摸索学习的环节…在上一章内容《C#Winform的DataGridView控件使用详解1-七种DataGridViewColumn类型使用方法》中,我们介绍了6种DataGridView列对象,在本章内容部中,我们将详细介绍DataGridViewTextBoxColumn对象的Cell设置(表头、表格内容、行序号)、右键弹出行操作(新建行、删除行、清空内容、复制、粘贴)。
DataGridView表格样式设置
DataGridView的表格样式包括表头(ColumnHeadersDefaultCellStyle)和表格内容(RowsDefaultCellStyle)的样式,此处我们对其的字体、对齐方式、点击自动排序和宽度可调节来进行设置:
1、字体与对齐方式设置// 设置表头居中,其对齐方式一共有10种,包含竖向的顶中底和水平的左中右以及NotSet this.dtLineHCurvePara.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //设置表头字体样式 this.dtLineHCurvePara.ColumnHeadersDefaultCellStyle.Font = new Font("宋体", 11); //设置单元格cell内容居中 this.dtLineHCurvePara.RowsDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter; //设置单元格cell字体样式 this.dtLineHCurvePara.RowsDefaultCellStyle.Font = new Font("宋体",
设置各种居中和字体样式后,结果如下显示:
2、对齐与表格排序的相互影响
但是当我们设置了表头和单元格均居中后,但发现表头并没有出现居中效果,如下图:
这里,我们需要调整一下表格列的参数,将排序模式设置为无排序:
设置了表头居中并没有显示居中效果的原因在于,该列排序模式为自动排序,所有该表头位置会出现一个便于排序点击的倒三角,会占据表头位置。
3、表格宽度调节
Excel表格的行高和列宽都能手动拉,为了满足一定的需求,我们需要设置是否可以调整行列尺寸(False:不能手动调整,True:可手动调整)。
DataGridView行序号设置
我们直接使用并填充数据的DataGridView默认是没有行号的,这里我们要利用表格的RowPostPaint函数,对表格进行重绘:
#region 显示行号 private void dtLineHCurvePara_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e) { var grid = sender as DataGridView; var rowidx = (e.RowIndex + 1).ToString(); var centerFormat = new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }; var headerBuunds = new System.Drawing.Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height); e.Graphics.DrawString(rowidx, new Font("宋体", 11), SystemBrushes.ControlText, headerBuunds, centerFormat); } #endregion
对表格进行重绘后,表格每添加一行,均会显示每行的行号,行号的字体也可以在代码中设置,表现如下:
右键弹出控件表格操作
为实现表格的会操作,给DataGridView绑定contextMenuStrip控件,然后在右键弹出菜单里面添加新建行、删除行、清除选中内容、复制和粘贴操作
首先在软件界面登录的时候,将表格与右键弹出框绑定。#region 编辑平曲线界面的Load事件 private void sFrmLineHCurveParaEdit_Load(object sender, EventArgs e) { this.dtLineHCurvePara.ContextMenuStrip = this.contextMenuStrip1; }
DataGridView新建行
右键弹出框,点击【新建行】按钮,即可在表格最后新增一行
#region 新建行 private void btnNewRow_Click(object sender, EventArgs e) { this.dtLineHCurvePara.Rows.Add(); } #endregion
DataGridView删除行
右键弹出框,点击【删除行】按钮,即可删除指定行号的行,如果要删除选中行,需要循环遍历DataGridView的SelectedRows对象,获取选中行的行序号,删除即可。
#region 删除行 private void btnDeleteRow_Click(object sender, EventArgs e) { int RowIndex = 1;//需要删除行的行序号 this.dtLineHCurvePara.Rows.RemoveAt(RowIndex); } #endregion
DataGridView清除内容
右键弹出框,点击【清除】按钮,即可将选中单元格的内容清空
#region 清除选中内容 private void btnClear_Click(object sender, EventArgs e) { //根据选中的datagridview单元格,对其内容赋值为"" int cellsCount = this.dtLineHCurvePara.SelectedCells.Count; //选中的单元格数量 for (int i = 0; i < cellsCount; i++)//循环选中的单元格 { dtLineHCurvePara.SelectedCells[i].Value = ""; } } #endregion
DataGridView复制
右键弹出框,点击【复制】按钮,即可将选中表格内容按照一定格式写入电脑剪切板,后续可直接在Excel表中粘贴即可,会保留一样的数据格式。
#region 复制选中的单元格内容 private void btnCopy_Click(object sender, EventArgs e) { try { Clipboard.SetText(this.dtLineHCurvePara.GetClipboardContent().GetData(DataFormats.Text).ToString()); } catch{} } #endregion
DataGridView粘贴
右键弹出框,点击【粘贴】按钮,即可将剪切板上的内容按照格式依序粘贴到DataGridView的单元格内。它可以自动判断需要的行,然后行自增,可以判断需要的列。列数不够会弹出提示。可以实现直接将Excel表格内容粘贴进来。
#region 粘贴剪切板内表格内容到DataGridView private void btnPaste_Click(object sender, EventArgs e) { try { string clipboardText = Clipboard.GetText(); //获取剪贴板中的内容 if (string.IsNullOrEmpty(clipboardText))//检测是否为空 { return; } int colnum = 0; //获取剪切板列数量 int rownum = 0; //获取剪切板行数量 for (int i = 0; i < clipboardText.Length; i++) { if (clipboardText.Substring(i, 1) == "\t") //每列 { colnum++; } if (clipboardText.Substring(i, 1) == "\n") //每行 { rownum++; } } //粘贴板上的数据来源于EXCEL时,每行末尾都有\n,来源于DataGridView是,最后一行末尾没有\n if (clipboardText.Substring(clipboardText.Length - 1, 1) == "\n") //剪切板最后一位 { rownum--; } //此时,行数列数均比真实行列内容对象少1 colnum = colnum / (rownum + 1); //????? object[,] data; //定义object类型的二维数组 data = new object[rownum + 1, colnum + 1]; //根据剪贴板的行列数实例化数组 //根据创建的data数组的行列数,检测是否当前datagridview行数大于等于data数组行数,少于则新建行 while (rownum > this.dtLineHCurvePara.RowCount - this.dtLineHCurvePara.SelectedCells[this.dtLineHCurvePara.SelectedCells.Count - 1].RowIndex - 1) //每次创建五行,直到数量足够 { for (int i = 0; i < 5; i++) { this.dtLineHCurvePara.Rows.Add(); } } // 检查剪切板内的列是否多于datagridview2内的列 if ((colnum + 1) > this.dtLineHCurvePara.ColumnCount) { MessageBox.Show("复制列数大于当前表格列数\n,请重新复制!"); return; } string rowStr = ""; //对数组各元素赋值 for (int i = 0; i <= rownum; i++) { for (int j = 0; j <= colnum; j++) { //一行中的其它列 if (j != colnum) { rowStr = clipboardText.Substring(0, clipboardText.IndexOf("\t")); clipboardText = clipboardText.Substring(clipboardText.IndexOf("\t") + 1); //将前面使用过的部分裁剪 } //一行中的最后一列(最后一个不为\r) if (j == colnum && clipboardText.IndexOf("\r") != -1) { rowStr = clipboardText.Substring(0, clipboardText.IndexOf("\r")); } //最后一行的最后一列(最后一个为\r) if (j == colnum && clipboardText.IndexOf("\r") == -1) { rowStr = clipboardText.Substring(0); } data[i, j] = rowStr; } //截取下一行及以后的数据 clipboardText = clipboardText.Substring(clipboardText.IndexOf("\n") + 1); } clipboardText = Clipboard.GetText(); int cellsCount = this.dtLineHCurvePara.SelectedCells.Count; //选中的单元格数量 int r1 = (this.dtLineHCurvePara.SelectedCells[cellsCount - 1].RowIndex); //选中的第一个的行下标 int r2 = (this.dtLineHCurvePara.SelectedCells[0].RowIndex); //选中最后一个的行下标 int c1 = (this.dtLineHCurvePara.SelectedCells[cellsCount - 1].ColumnIndex); //选中的第一个的列下标 int c2 = (this.dtLineHCurvePara.SelectedCells[0].ColumnIndex); //选中的最后一个的列下表 int rowIndex = Math.Abs(r2 - r1) + 1; //选中单元格的行数量 int colIndex = Math.Abs(c2 - c1) + 1; //选中但换个的列数量 if (colIndex != colnum + 1 || rowIndex != rownum + 1) //选中的行列数量与剪切板内的行列数量不一致 { //如果区域不一致,选取选中的第一格单元格作为锚点 for (int i = 0; i <= rownum; i++) //遍历行 { for (int j = 0; j <= colnum; j++) //遍历列 { this.dtLineHCurvePara.Rows[i + r1].Cells[j + c1].Value = data[i, j]; } } } else { for (int i = 0; i <= rownum; i++) //遍历行 { for (int j = 0; j <= colnum; j++) //遍历列 { this.dtLineHCurvePara.Rows[i + r1].Cells[j + c1].Value = data[i, j]; } } } } catch { } } #endregion
-
表格控件的使用 WinForm WebForm
2010-10-23 21:15:44此控件用于处理数据表格,可以进行一些常用的处理方式,例如分页显示功能,以及处理一些常用的技巧 :例如可以对不同的数据行进行颜色的处理 -
winform的一个程序,用的GridControl表格控件。
2021-03-12 11:57:57<p><img alt="" height="95" src="https://img-ask.csdnimg.cn/upload/1615521304150.png" width="648" /></p> 我的列表数据是存的Datatable然后转存入xml文件,程序加载的时候再去xml文件中读取显示出来... -
Winform PropertyGrid控件
2022-01-17 15:43:38Winform PropertyGrid控件 -
Flexcell和spread两种表格控件的对比
2013-08-06 17:58:00Flexcell和spread studio for .net两种表格控件的对比 -
(八十六)c#Winform自定义控件-表格优化-HZHControls
2020-05-12 08:20:06出处:http://www.hzhcontrols.com/原文:http://www.hzhcontrols.com/blog-149.html本文版权归...入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com... -
C# Winform使用ListVIew控件制作表格
2018-12-12 15:13:191、找到ListVIew拖到窗体中 2、点击右上角,设置视图为 Details,或者直接在属性里面设置View为Details 3、添加列表头:点击属性Columns 完后效果如下: 4、添加行表头:点击...System.ArgumentOutOf... -
最近发现的一个c# winform的一个很好用很强大的excel控件 reogrid控件
2019-07-23 09:57:09转载地址...还可参考下,使用ListView制作表格https://blog.csdn.net/oMoDao1/article/details/84972984 使用ReportView制作报表。 https://blog.csdn.net/langwen2048/article/de... -
(转)WinForm中的各种表格控件
2012-12-04 10:44:001.DataGridView .net 2.0框架自带的网格控件 2.SourceGrid SourceGrid 是一个的完全地用C#开发的Windows窗体控件;我的目标是产生一个简单的但是灵活的(网格)grid,每当使改变一个表格式的一系列... -
WinForm列表控件美化
2021-12-14 21:07:02WinForm列表控件的美化 -
C# Winform 开源控件
2012-08-23 01:28:00C# WinForm开发系列 - Open-Source Controls 整理了一些在WinForm开发中可以使用的开源组件.(文章及相关代码搜集自网络,仅供学习参考,版权属于原作者!... 2007的Ribbon风格面板...2. .NET中最全功能的表格控 -
C#winform究竟怎么创建一个表格?有 表格 控件吗?
2022-04-06 19:53:03究竟怎么在C#winform中创建一个表格?...C#winform下究竟有没有表格控件? 不管是不用数据库使用datagridview,还是使用gridcontrol,都可以! //用的版本是VS2019,.NETframewo4.7.2,创建的是winform程序 -
c#Winform自定义控件-目录
2019-09-06 20:59:24入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git 如果... -
WinForm 控制 控件在窗体上的显示位置
2022-05-11 15:02:40第一种方法: //控制一个控件的显示位置 button1.Top = 100; button1.Left = 100; 第二种方法: //给一个控件赋值 的两种方法 button1.Location = new Point(500,500); ... -
SNF开发平台WinForm-Grid表格控件大全
2017-08-21 13:25:00那么下面就介绍一些我们在表格控件里常用的方便的控件: 1、Grid表格查询条 Grid表格下拉 3、Grid表格弹框选择控件ButtonEdit。 4、Grid表格下拉搜索控件 5、Grid表格下拉多选控件 1.Grid表格查询... -
C# WinForm常用的开源控件
2018-10-28 13:00:58记录C# WinForm常用的开源控件集1、Circular ProgressBar for WinForm2、Live Charts 1、Circular ProgressBar for WinForm Github地址:https://github.com/falahati/CircularProgressBar 2、Live Charts Github... -
Winform分页控件使用详细介绍
2018-06-15 13:54:26自从上篇随笔《 Winform分页控件最新版本发布,并提供基于DotNetBar界面的版本》介绍了最新版本的分页控件,并提供下载使用后,很多人对分页控件非常感兴趣(毕竟Winform数据分页是很 -
c#教程之.Net WInform开发笔记(三)谈谈自制控件(自定
2021-02-09 08:08:35这次谈谈自制控件,也就是自定义控件,先上图,再说1.扩展OpenFileDialog,在OpenFileDialog中添加各种文件(.txt,.jpg,.excel等等)的预览功能2.重写ListBox,增加折叠、鼠标背影、分类等功能-----------------------... -
WinForm列表控件开启双缓冲
2021-12-14 20:22:57三种方法开启WinForm列表控件的双缓冲,解决闪烁卡顿的问题 -
winform chart控件 滚动条
2021-11-03 17:06:19当数据库中数据过多时,往往无法在一页中展示,所以非常需要一个滚动条来调节页面内容,那么C#中chart控件如何实现滚动条? 还是以软件【银行业会计技能训练系统】为例,如下图,X轴内容较多,如何实现如下效果的... -
Winform控件之DataGridView数据控件(一)
2015-05-30 11:07:06DataGridView控件提高了一种强大而灵活的以表格形式显示数据的方式。用户可以使用 DataGridView控件来显示少量数据的只读视图,也可以对其进行缩放以显示特大数据集的可编辑视图。 扩展 DataGridView控件有很种... -
WinForm基础控件--分组类控件
2017-11-04 05:07:26Panel控件 显示的效果: 实例 一个主窗体、4个子窗体 主窗体: 子窗体1 ... Multiline属性允许多行选项卡 Appearance属性绘制成按钮或常规选项卡 实例压缩包页面 tabPages属性添加和删除 表格事件