• (三十二)c#Winform自定义控件-表格-HZHControls


    官网

    http://www.hzhcontrols.com

    前提

    入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

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

    码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

    如果觉得写的还行,请点个 star 支持一下吧

    欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492

    目录

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

    准备工作

    表格控件将拆分为2部分,1:行元素控件,2:列表控件

    为了具有更好的扩展性,更加的open,使用接口对行元素进行约束,当行样式或功能不满足你的需求的时候,可以自定义一个行元素,实现接口控件,然后将类型指定给列表控件即可

    表格控件用到了分页控件,如果你还没有对分页控件进行了解,请移步查看

    (十二)c#Winform自定义控件-分页控件

    开始

    定义一些辅助东西

    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 }
    View Code
     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 }
    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

    完整代码

      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 }
    View Code
      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 }
    View Code

    如果你仔细看,你会发现行我用了类型进行传入,当你需要更丰富的行内容的时候,可以自定义行控件,然后通过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 点个星 星吧

  • 相关阅读:
    POJ1149 最大流经典建图PIG
    POJ1149 最大流经典建图PIG
    POJ3322滚箱子游戏(不错)
    POJ3322滚箱子游戏(不错)
    UVA11020 优势人群(multiset)
    UVA11020 优势人群(multiset)
    UVA11019KMP(二维矩阵匹配出现次数)
    UVA11019KMP(二维矩阵匹配出现次数)
    LA3942字典树+递推
    LA3942字典树+递推
  • 原文地址:https://www.cnblogs.com/bfyx/p/11364737.html
Copyright © 2020-2023  润新知