欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-29 10:04:42
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control 如果觉得写的还行,请点个 star 支持一下吧 欢迎前来交流探讨: 企鹅群568015492 目录 ......

前提

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

开源地址:

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

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

目录

准备工作

表格控件将拆分为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 }
 1 namespace hzh_controls.controls
 2 {
 3     partial class ucdatagridviewrow
 4     {
 5         /// <summary> 
 6         /// 必需的设计器变量。
 7         /// </summary>
 8         private system.componentmodel.icontainer components = null;
 9 
10         /// <summary> 
11         /// 清理所有正在使用的资源。
12         /// </summary>
13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
14         protected override void dispose(bool disposing)
15         {
16             if (disposing && (components != null))
17             {
18                 components.dispose();
19             }
20             base.dispose(disposing);
21         }
22 
23         #region 组件设计器生成的代码
24 
25         /// <summary> 
26         /// 设计器支持所需的方法 - 不要
27         /// 使用代码编辑器修改此方法的内容。
28         /// </summary>
29         private void initializecomponent()
30         {
31             this.ucsplitline_h1 = new hzh_controls.controls.ucsplitline_h();
32             this.pancells = new system.windows.forms.tablelayoutpanel();
33             this.suspendlayout();
34             // 
35             // ucsplitline_h1
36             // 
37             this.ucsplitline_h1.backcolor = system.drawing.color.fromargb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232)))));
38             this.ucsplitline_h1.dock = system.windows.forms.dockstyle.bottom;
39             this.ucsplitline_h1.location = new system.drawing.point(0, 55);
40             this.ucsplitline_h1.name = "ucsplitline_h1";
41             this.ucsplitline_h1.size = new system.drawing.size(661, 1);
42             this.ucsplitline_h1.tabindex = 0;
43             this.ucsplitline_h1.tabstop = false;
44             // 
45             // pancells
46             // 
47             this.pancells.columncount = 1;
48             this.pancells.columnstyles.add(new system.windows.forms.columnstyle(system.windows.forms.sizetype.percent, 100f));
49             this.pancells.columnstyles.add(new system.windows.forms.columnstyle(system.windows.forms.sizetype.absolute, 20f));
50             this.pancells.dock = system.windows.forms.dockstyle.fill;
51             this.pancells.location = new system.drawing.point(0, 0);
52             this.pancells.name = "pancells";
53             this.pancells.rowcount = 1;
54             this.pancells.rowstyles.add(new system.windows.forms.rowstyle(system.windows.forms.sizetype.percent, 100f));
55             this.pancells.rowstyles.add(new system.windows.forms.rowstyle(system.windows.forms.sizetype.absolute, 20f));
56             this.pancells.size = new system.drawing.size(661, 55);
57             this.pancells.tabindex = 1;
58             // 
59             // ucdatagridviewitem
60             // 
61             this.autoscalemode = system.windows.forms.autoscalemode.none;
62             this.backcolor = system.drawing.color.white;
63             this.controls.add(this.pancells);
64             this.controls.add(this.ucsplitline_h1);
65             this.name = "ucdatagridviewitem";
66             this.size = new system.drawing.size(661, 56);
67             this.resumelayout(false);
68 
69         }
70 
71         #endregion
72 
73         private ucsplitline_h ucsplitline_h1;
74         private system.windows.forms.tablelayoutpanel pancells;
75     }
76 }

 

接下来就是列表控件了

添加一个用户控件,命名ucdatagridview

属性

  1  #region 属性
  2         private font m_headfont = new font("微软雅黑", 12f);
  3         /// <summary>
  4         /// 标题字体
  5         /// </summary>
  6         [description("标题字体"), category("自定义")]
  7         public font headfont
  8         {
  9             get { return m_headfont; }
 10             set { m_headfont = value; }
 11         }
 12         private color m_headtextcolor = color.black;
 13         /// <summary>
 14         /// 标题字体颜色
 15         /// </summary>
 16         [description("标题文字颜色"), category("自定义")]
 17         public color headtextcolor
 18         {
 19             get { return m_headtextcolor; }
 20             set { m_headtextcolor = value; }
 21         }
 22 
 23         private bool m_isshowhead = true;
 24         /// <summary>
 25         /// 是否显示标题
 26         /// </summary>
 27         [description("是否显示标题"), category("自定义")]
 28         public bool isshowhead
 29         {
 30             get { return m_isshowhead; }
 31             set
 32             {
 33                 m_isshowhead = value;
 34                 panhead.visible = value;
 35                 if (m_page != null)
 36                 {
 37                     resetshowcount();
 38                     m_page.pagesize = m_showcount;
 39                 }
 40             }
 41         }
 42         private int m_headheight = 40;
 43         /// <summary>
 44         /// 标题高度
 45         /// </summary>
 46         [description("标题高度"), category("自定义")]
 47         public int headheight
 48         {
 49             get { return m_headheight; }
 50             set
 51             {
 52                 m_headheight = value;
 53                 panhead.height = value;
 54             }
 55         }
 56 
 57         private bool m_isshowcheckbox = false;
 58         /// <summary>
 59         /// 是否显示复选框
 60         /// </summary>
 61         [description("是否显示选择框"), category("自定义")]
 62         public bool isshowcheckbox
 63         {
 64             get { return m_isshowcheckbox; }
 65             set
 66             {
 67                 if (value != m_isshowcheckbox)
 68                 {
 69                     m_isshowcheckbox = value;
 70                     loadcolumns();
 71                 }
 72             }
 73         }
 74 
 75         private int m_rowheight = 40;
 76         /// <summary>
 77         /// 行高
 78         /// </summary>
 79         [description("数据行高"), category("自定义")]
 80         public int rowheight
 81         {
 82             get { return m_rowheight; }
 83             set { m_rowheight = value; }
 84         }
 85 
 86         private int m_showcount = 0;
 87         /// <summary>
 88         /// 
 89         /// </summary>
 90         [description("可显示个数"), category("自定义")]
 91         public int showcount
 92         {
 93             get { return m_showcount; }
 94             private set
 95             {
 96                 m_showcount = value;
 97                 if (m_page != null)
 98                 {
 99                     m_page.pagesize = value;
100                 }
101             }
102         }
103 
104         private list<datagridviewcolumnentity> m_columns;
105         /// <summary>
106         /// 列
107         /// </summary>
108         [description("列"), category("自定义")]
109         public list<datagridviewcolumnentity> columns
110         {
111             get { return m_columns; }
112             set
113             {
114                 m_columns = value;
115                 loadcolumns();
116             }
117         }
118 
119         private object m_datasource;
120         /// <summary>
121         /// 数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的datasource
122         /// </summary>
123         [description("数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的datasource"), category("自定义")]
124         public object datasource
125         {
126             get { return m_datasource; }
127             set
128             {
129                 if (value == null)
130                     return;
131                 if (!(m_datasource is datatable) && (!typeof(ilist).isassignablefrom(value.gettype())))
132                 {
133                     throw new exception("数据源不是有效的数据类型,请使用datatable或列表");
134                 }
135 
136                 m_datasource = value;
137                 reloadsource();
138             }
139         }
140 
141         public list<idatagridviewrow> rows { get; private set; }
142 
143         private type m_rowtype = typeof(ucdatagridviewrow);
144         /// <summary>
145         /// 行元素类型,默认ucdatagridviewitem
146         /// </summary>
147         [description("行控件类型,默认ucdatagridviewrow,如果不满足请自定义行控件实现接口idatagridviewrow"), category("自定义")]
148         public type rowtype
149         {
150             get { return m_rowtype; }
151             set
152             {
153                 if (value == null)
154                     return;
155                 if (!typeof(idatagridviewrow).isassignablefrom(value) || !value.issubclassof(typeof(control)))
156                     throw new exception("行控件没有实现idatagridviewrow接口");
157                 m_rowtype = value;
158             }
159         }
160         idatagridviewrow m_selectrow = null;
161         /// <summary>
162         /// 选中的节点
163         /// </summary>
164         [description("选中行"), category("自定义")]
165         public idatagridviewrow selectrow
166         {
167             get { return m_selectrow; }
168             private set { m_selectrow = value; }
169         }
170 
171 
172         /// <summary>
173         /// 选中的行,如果显示checkbox,则以checkbox选中为准
174         /// </summary>
175         [description("选中的行,如果显示checkbox,则以checkbox选中为准"), category("自定义")]
176         public list<idatagridviewrow> selectrows
177         {
178             get
179             {
180                 if (m_isshowcheckbox)
181                 {
182                     return rows.findall(p => p.ischecked);
183                 }
184                 else
185                     return new list<idatagridviewrow>() { m_selectrow };
186             }
187         }
188 
189 
190         private ucpagercontrolbase m_page = null;
191         /// <summary>
192         /// 翻页控件
193         /// </summary>
194         [description("翻页控件,如果ucpagercontrol不满足你的需求,请自定义翻页控件并继承ucpagercontrolbase"), category("自定义")]
195         public ucpagercontrolbase page
196         {
197             get { return m_page; }
198             set
199             {
200                 m_page = value;
201                 if (value != null)
202                 {
203                     if (!typeof(ipagecontrol).isassignablefrom(value.gettype()) || !value.gettype().issubclassof(typeof(ucpagercontrolbase)))
204                         throw new exception("翻页控件没有继承ucpagercontrolbase");
205                     panpage.visible = value != null;
206                     m_page.showsourcechanged += page_showsourcechanged;
207                     m_page.dock = dockstyle.fill;
208                     this.panpage.controls.clear();
209                     this.panpage.controls.add(m_page);
210                     resetshowcount();
211                     m_page.pagesize = showcount;
212                     this.datasource = m_page.getcurrentsource();
213                 }
214                 else
215                 {
216                     m_page = null;
217                 }
218             }
219         }
220 
221         void page_showsourcechanged(object currentsource)
222         {
223             this.datasource = currentsource;
224         }
225 
226         #region 事件
227         [description("选中标题选择框事件"), category("自定义")]
228         public eventhandler headcheckboxchangeevent;
229         [description("标题点击事件"), category("自定义")]
230         public eventhandler headcolumnclickevent;
231         [description("项点击事件"), category("自定义")]
232         public event datagridvieweventhandler itemclick;
233         [description("数据源改变事件"), category("自定义")]
234         public event datagridvieweventhandler sourcechanged;
235         #endregion
236         #endregion

一些私有的方法

 1   #region 私有方法
 2         #region 加载column
 3         /// <summary>
 4         /// 功能描述:加载column
 5         /// 作  者:hzh
 6         /// 创建日期:2019-08-08 17:51:50
 7         /// 任务编号:pos
 8         /// </summary>
 9         private void loadcolumns()
10         {
11             try
12             {
13                 if (designmode)
14                 { return; }
15 
16                 controlhelper.freezecontrol(this.panhead, true);
17                 this.pancolumns.controls.clear();
18                 this.pancolumns.columnstyles.clear();
19 
20                 if (m_columns != null && m_columns.count() > 0)
21                 {
22                     int intcolumnscount = m_columns.count();
23                     if (m_isshowcheckbox)
24                     {
25                         intcolumnscount++;
26                     }
27                     this.pancolumns.columncount = intcolumnscount;
28                     for (int i = 0; i < intcolumnscount; i++)
29                     {
30                         control c = null;
31                         if (i == 0 && m_isshowcheckbox)
32                         {
33                             this.pancolumns.columnstyles.add(new system.windows.forms.columnstyle(sizetype.absolute, 30f));
34 
35                             uccheckbox box = new uccheckbox();
36                             box.textvalue = "";
37                             box.size = new size(30, 30);
38                             box.checkedchangeevent += (a, b) =>
39                             {
40                                 rows.foreach(p => p.ischecked = box.checked);
41                                 if (headcheckboxchangeevent != null)
42                                 {
43                                     headcheckboxchangeevent(a, b);
44                                 }
45                             };
46                             c = box;
47                         }
48                         else
49                         {
50                             var item = m_columns[i - (m_isshowcheckbox ? 1 : 0)];
51                             this.pancolumns.columnstyles.add(new system.windows.forms.columnstyle(item.widthtype, item.width));
52                             label lbl = new label();
53                             lbl.name = "dgvcolumns_" + i;
54                             lbl.text = item.headtext;
55                             lbl.font = m_headfont;
56                             lbl.forecolor = m_headtextcolor;
57                             lbl.textalign = contentalignment.middlecenter;
58                             lbl.autosize = false;
59                             lbl.dock = dockstyle.fill;
60                             lbl.mousedown += (a, b) =>
61                             {
62                                 if (headcolumnclickevent != null)
63                                 {
64                                     headcolumnclickevent(a, b);
65                                 }
66                             };
67                             c = lbl;
68                         }
69                         this.pancolumns.controls.add(c, i, 0);
70                     }
71 
72                 }
73             }
74             finally
75             {
76                 controlhelper.freezecontrol(this.panhead, false);
77             }
78         }
79         #endregion
80 
81         /// <summary>
82         /// 功能描述:获取显示个数
83         /// 作  者:hzh
84         /// 创建日期:2019-03-05 10:02:58
85         /// 任务编号:pos
86         /// </summary>
87         /// <returns>返回值</returns>
88         private void resetshowcount()
89         {
90             if (designmode)
91             { return; }
92             showcount = this.panrow.height / (m_rowheight);
93             int intcha = this.panrow.height % (m_rowheight);
94             m_rowheight += intcha / showcount;
95         }
96         #endregion

几个事件

 1  #region 事件
 2         void rowsourcechanged(object sender, datagridvieweventargs e)
 3         {
 4             if (sourcechanged != null)
 5                 sourcechanged(sender, e);
 6         }
 7         private void setselectrow(control item, datagridvieweventargs e)
 8         {
 9             try
10             {
11                 controlhelper.freezecontrol(this, true);
12                 if (item == null)
13                     return;
14                 if (item.visible == false)
15                     return;
16                 this.findform().activecontrol = this;
17                 this.findform().activecontrol = item;
18                 if (m_selectrow != null)
19                 {
20                     if (m_selectrow == item)
21                         return;
22                     m_selectrow.setselect(false);
23                 }
24                 m_selectrow = item as idatagridviewrow;
25                 m_selectrow.setselect(true);
26                 if (itemclick != null)
27                 {
28                     itemclick(item, e);
29                 }
30                 if (this.panrow.controls.count > 0)
31                 {
32                     if (item.location.y < 0)
33                     {
34                         this.panrow.autoscrollposition = new point(0, math.abs(this.panrow.controls[this.panrow.controls.count - 1].location.y) + item.location.y);
35                     }
36                     else if (item.location.y + m_rowheight > this.panrow.height)
37                     {
38                         this.panrow.autoscrollposition = new point(0, math.abs(this.panrow.autoscrollposition.y) + item.location.y - this.panrow.height + m_rowheight);
39                     }
40                 }
41             }
42             finally
43             {
44                 controlhelper.freezecontrol(this, false);
45             }
46         }
47         private void ucdatagridview_resize(object sender, eventargs e)
48         {
49             resetshowcount();
50             reloadsource();
51         }
52         #endregion

对外公开的函数

  1  #region 公共函数
  2         /// <summary>
  3         /// 刷新数据
  4         /// </summary>
  5         public void reloadsource()
  6         {
  7             if (designmode)
  8             { return; }
  9             try
 10             {
 11                 if (m_columns == null || m_columns.count <= 0)
 12                     return;
 13 
 14                 controlhelper.freezecontrol(this.panrow, true);
 15                 this.panrow.controls.clear();
 16                 rows = new list<idatagridviewrow>();
 17                 if (m_datasource != null)
 18                 {
 19                     int intindex = 0;
 20                     control lastitem = null;
 21 
 22                     int intsourcecount = 0;
 23                     if (m_datasource is datatable)
 24                     {
 25                         intsourcecount = (m_datasource as datatable).rows.count;
 26                     }
 27                     else if (typeof(ilist).isassignablefrom(m_datasource.gettype()))
 28                     {
 29                         intsourcecount = (m_datasource as ilist).count;
 30                     }
 31 
 32                     foreach (control item in this.panrow.controls)
 33                     {
 34 
 35 
 36                         if (intindex >= intsourcecount)
 37                         {
 38                             item.visible = false;
 39                         }
 40                         else
 41                         {
 42                             var row = (item as idatagridviewrow);
 43                             row.isshowcheckbox = m_isshowcheckbox;
 44                             if (m_datasource is datatable)
 45                             {
 46                                 row.datasource = (m_datasource as datatable).rows[intindex];
 47                             }
 48                             else
 49                             {
 50                                 row.datasource = (m_datasource as ilist)[intindex];
 51                             }
 52                             row.bindingcelldata();
 53                             item.height = m_rowheight;
 54                             item.visible = true;
 55                             item.bringtofront();
 56                             if (lastitem == null)
 57                                 lastitem = item;
 58                             rows.add(row);
 59                         }
 60                         intindex++;
 61                     }
 62 
 63                     if (intindex < intsourcecount)
 64                     {
 65                         for (int i = intindex; i < intsourcecount; i++)
 66                         {
 67                             idatagridviewrow row = (idatagridviewrow)activator.createinstance(m_rowtype);
 68                             if (m_datasource is datatable)
 69                             {
 70                                 row.datasource = (m_datasource as datatable).rows[i];
 71                             }
 72                             else
 73                             {
 74                                 row.datasource = (m_datasource as ilist)[i];
 75                             }
 76                             row.columns = m_columns;
 77                             list<control> lstcells = new list<control>();
 78                             row.isshowcheckbox = m_isshowcheckbox;
 79                             row.reloadcells();
 80                             row.bindingcelldata();
 81 
 82 
 83                             control rowcontrol = (row as control);
 84                             rowcontrol.height = m_rowheight;
 85                             this.panrow.controls.add(rowcontrol);
 86                             rowcontrol.dock = dockstyle.top;
 87                             row.cellclick += (a, b) => { setselectrow(rowcontrol, b); };
 88                             row.checkboxchangeevent += (a, b) => { setselectrow(rowcontrol, b); };
 89                             row.sourcechanged += rowsourcechanged;
 90                             rowcontrol.bringtofront();
 91                             rows.add(row);
 92 
 93                             if (lastitem == null)
 94                                 lastitem = rowcontrol;
 95                         }
 96                     }
 97                     if (lastitem != null && intsourcecount == m_showcount)
 98                     {
 99                         lastitem.height = this.panrow.height - (m_showcount - 1) * m_rowheight;
100                     }
101                 }
102             }
103             finally
104             {
105                 controlhelper.freezecontrol(this.panrow, false);
106             }
107         }
108 
109 
110         /// <summary>
111         /// 快捷键
112         /// </summary>
113         /// <param name="msg"></param>
114         /// <param name="keydata"></param>
115         /// <returns></returns>
116         protected override bool processcmdkey(ref message msg, keys keydata)
117         {
118             if (keydata == keys.up)
119             {
120                 previous();
121             }
122             else if (keydata == keys.down)
123             {
124                 next();
125             }
126             else if (keydata == keys.home)
127             {
128                 first();
129             }
130             else if (keydata == keys.end)
131             {
132                 end();
133             }
134             return base.processcmdkey(ref msg, keydata);
135         }
136         /// <summary>
137         /// 选中第一个
138         /// </summary>
139         public void first()
140         {
141             if (rows == null || rows.count <= 0)
142                 return;
143             control c = null;
144             c = (rows[0] as control);
145             setselectrow(c, new datagridvieweventargs() { rowindex = 0 });
146         }
147         /// <summary>
148         /// 选中上一个
149         /// </summary>
150         public void previous()
151         {
152             if (rows == null || rows.count <= 0)
153                 return;
154             control c = null;
155 
156             int index = rows.indexof(m_selectrow);
157             if (index - 1 >= 0)
158             {
159                 c = (rows[index - 1] as control);
160                 setselectrow(c, new datagridvieweventargs() { rowindex = index - 1 });
161             }
162         }
163         /// <summary>
164         /// 选中下一个
165         /// </summary>
166         public void next()
167         {
168             if (rows == null || rows.count <= 0)
169                 return;
170             control c = null;
171 
172             int index = rows.indexof(m_selectrow);
173             if (index + 1 < rows.count)
174             {
175                 c = (rows[index + 1] as control);
176                 setselectrow(c, new datagridvieweventargs() { rowindex = index + 1 });
177             }
178         }
179         /// <summary>
180         /// 选中最后一个
181         /// </summary>
182         public void end()
183         {
184             if (rows == null || rows.count <= 0)
185                 return;
186             control c = null;
187             c = (rows[rows.count - 1] as control);
188             setselectrow(c, new datagridvieweventargs() { rowindex = rows.count - 1 });
189         }
190 
191         #endregion

完整代码

  1 // 版权所有  黄正辉  交流群:568015492   qq:623128629
  2 // 文件名称:ucdatagridview.cs
  3 // 创建日期:2019-08-15 15:59:25
  4 // 功能描述:datagridview
  5 // 项目地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
  6 using system;
  7 using system.collections.generic;
  8 using system.componentmodel;
  9 using system.drawing;
 10 using system.data;
 11 using system.linq;
 12 using system.text;
 13 using system.windows.forms;
 14 using system.collections;
 15 
 16 namespace hzh_controls.controls
 17 {
 18     public partial class ucdatagridview : usercontrol
 19     {
 20         #region 属性
 21         private font m_headfont = new font("微软雅黑", 12f);
 22         /// <summary>
 23         /// 标题字体
 24         /// </summary>
 25         [description("标题字体"), category("自定义")]
 26         public font headfont
 27         {
 28             get { return m_headfont; }
 29             set { m_headfont = value; }
 30         }
 31         private color m_headtextcolor = color.black;
 32         /// <summary>
 33         /// 标题字体颜色
 34         /// </summary>
 35         [description("标题文字颜色"), category("自定义")]
 36         public color headtextcolor
 37         {
 38             get { return m_headtextcolor; }
 39             set { m_headtextcolor = value; }
 40         }
 41 
 42         private bool m_isshowhead = true;
 43         /// <summary>
 44         /// 是否显示标题
 45         /// </summary>
 46         [description("是否显示标题"), category("自定义")]
 47         public bool isshowhead
 48         {
 49             get { return m_isshowhead; }
 50             set
 51             {
 52                 m_isshowhead = value;
 53                 panhead.visible = value;
 54                 if (m_page != null)
 55                 {
 56                     resetshowcount();
 57                     m_page.pagesize = m_showcount;
 58                 }
 59             }
 60         }
 61         private int m_headheight = 40;
 62         /// <summary>
 63         /// 标题高度
 64         /// </summary>
 65         [description("标题高度"), category("自定义")]
 66         public int headheight
 67         {
 68             get { return m_headheight; }
 69             set
 70             {
 71                 m_headheight = value;
 72                 panhead.height = value;
 73             }
 74         }
 75 
 76         private bool m_isshowcheckbox = false;
 77         /// <summary>
 78         /// 是否显示复选框
 79         /// </summary>
 80         [description("是否显示选择框"), category("自定义")]
 81         public bool isshowcheckbox
 82         {
 83             get { return m_isshowcheckbox; }
 84             set
 85             {
 86                 if (value != m_isshowcheckbox)
 87                 {
 88                     m_isshowcheckbox = value;
 89                     loadcolumns();
 90                 }
 91             }
 92         }
 93 
 94         private int m_rowheight = 40;
 95         /// <summary>
 96         /// 行高
 97         /// </summary>
 98         [description("数据行高"), category("自定义")]
 99         public int rowheight
100         {
101             get { return m_rowheight; }
102             set { m_rowheight = value; }
103         }
104 
105         private int m_showcount = 0;
106         /// <summary>
107         /// 
108         /// </summary>
109         [description("可显示个数"), category("自定义")]
110         public int showcount
111         {
112             get { return m_showcount; }
113             private set
114             {
115                 m_showcount = value;
116                 if (m_page != null)
117                 {
118                     m_page.pagesize = value;
119                 }
120             }
121         }
122 
123         private list<datagridviewcolumnentity> m_columns;
124         /// <summary>
125         /// 列
126         /// </summary>
127         [description("列"), category("自定义")]
128         public list<datagridviewcolumnentity> columns
129         {
130             get { return m_columns; }
131             set
132             {
133                 m_columns = value;
134                 loadcolumns();
135             }
136         }
137 
138         private object m_datasource;
139         /// <summary>
140         /// 数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的datasource
141         /// </summary>
142         [description("数据源,支持列表或table,如果使用翻页控件,请使用翻页控件的datasource"), category("自定义")]
143         public object datasource
144         {
145             get { return m_datasource; }
146             set
147             {
148                 if (value == null)
149                     return;
150                 if (!(m_datasource is datatable) && (!typeof(ilist).isassignablefrom(value.gettype())))
151                 {
152                     throw new exception("数据源不是有效的数据类型,请使用datatable或列表");
153                 }
154 
155                 m_datasource = value;
156                 reloadsource();
157             }
158         }
159 
160         public list<idatagridviewrow> rows { get; private set; }
161 
162         private type m_rowtype = typeof(ucdatagridviewrow);
163         /// <summary>
164         /// 行元素类型,默认ucdatagridviewitem
165         /// </summary>
166         [description("行控件类型,默认ucdatagridviewrow,如果不满足请自定义行控件实现接口idatagridviewrow"), category("自定义")]
167         public type rowtype
168         {
169             get { return m_rowtype; }
170             set
171             {
172                 if (value == null)
173                     return;
174                 if (!typeof(idatagridviewrow).isassignablefrom(value) || !value.issubclassof(typeof(control)))
175                     throw new exception("行控件没有实现idatagridviewrow接口");
176                 m_rowtype = value;
177             }
178         }
179         idatagridviewrow m_selectrow = null;
180         /// <summary>
181         /// 选中的节点
182         /// </summary>
183         [description("选中行"), category("自定义")]
184         public idatagridviewrow selectrow
185         {
186             get { return m_selectrow; }
187             private set { m_selectrow = value; }
188         }
189 
190 
191         /// <summary>
192         /// 选中的行,如果显示checkbox,则以checkbox选中为准
193         /// </summary>
194         [description("选中的行,如果显示checkbox,则以checkbox选中为准"), category("自定义")]
195         public list<idatagridviewrow> selectrows
196         {
197             get
198             {
199                 if (m_isshowcheckbox)
200                 {
201                     return rows.findall(p => p.ischecked);
202                 }
203                 else
204                     return new list<idatagridviewrow>() { m_selectrow };
205             }
206         }
207 
208 
209         private ucpagercontrolbase m_page = null;
210         /// <summary>
211         /// 翻页控件
212         /// </summary>
213         [description("翻页控件,如果ucpagercontrol不满足你的需求,请自定义翻页控件并继承ucpagercontrolbase"), category("自定义")]
214         public ucpagercontrolbase page
215         {
216             get { return m_page; }
217             set
218             {
219                 m_page = value;
220                 if (value != null)
221                 {
222                     if (!typeof(ipagecontrol).isassignablefrom(value.gettype()) || !value.gettype().issubclassof(typeof(ucpagercontrolbase)))
223                         throw new exception("翻页控件没有继承ucpagercontrolbase");
224                     panpage.visible = value != null;
225                     m_page.showsourcechanged += page_showsourcechanged;
226                     m_page.dock = dockstyle.fill;
227                     this.panpage.controls.clear();
228                     this.panpage.controls.add(m_page);
229                     resetshowcount();
230                     m_page.pagesize = showcount;
231                     this.datasource = m_page.getcurrentsource();
232                 }
233                 else
234                 {
235                     m_page = null;
236                 }
237             }
238         }
239 
240         void page_showsourcechanged(object currentsource)
241         {
242             this.datasource = currentsource;
243         }
244 
245         #region 事件
246         [description("选中标题选择框事件"), category("自定义")]
247         public eventhandler headcheckboxchangeevent;
248         [description("标题点击事件"), category("自定义")]
249         public eventhandler headcolumnclickevent;
250         [description("项点击事件"), category("自定义")]
251         public event datagridvieweventhandler itemclick;
252         [description("数据源改变事件"), category("自定义")]
253         public event datagridvieweventhandler sourcechanged;
254         #endregion
255         #endregion
256 
257         public ucdatagridview()
258         {
259             initializecomponent();
260         }
261 
262         #region 私有方法
263         #region 加载column
264         /// <summary>
265         /// 功能描述:加载column
266         /// 作  者:hzh
267         /// 创建日期:2019-08-08 17:51:50
268         /// 任务编号:pos
269         /// </summary>
270         private void loadcolumns()
271         {
272             try
273             {
274                 if (designmode)
275                 { return; }
276 
277                 controlhelper.freezecontrol(this.panhead, true);
278                 this.pancolumns.controls.clear();
279                 this.pancolumns.columnstyles.clear();
280 
281                 if (m_columns != null && m_columns.count() > 0)
282                 {
283                     int intcolumnscount = m_columns.count();
284                     if (m_isshowcheckbox)
285                     {
286                         intcolumnscount++;
287                     }
288                     this.pancolumns.columncount = intcolumnscount;
289                     for (int i = 0; i < intcolumnscount; i++)
290                     {
291                         control c = null;
292                         if (i == 0 && m_isshowcheckbox)
293                         {
294                             this.pancolumns.columnstyles.add(new system.windows.forms.columnstyle(sizetype.absolute, 30f));
295 
296                             uccheckbox box = new uccheckbox();
297                             box.textvalue = "";
298                             box.size = new size(30, 30);
299                             box.checkedchangeevent += (a, b) =>
300                             {
301                                 rows.foreach(p => p.ischecked = box.checked);
302                                 if (headcheckboxchangeevent != null)
303                                 {
304                                     headcheckboxchangeevent(a, b);
305                                 }
306                             };
307                             c = box;
308                         }
309                         else
310                         {
311                             var item = m_columns[i - (m_isshowcheckbox ? 1 : 0)];
312                             this.pancolumns.columnstyles.add(new system.windows.forms.columnstyle(item.widthtype, item.width));
313                             label lbl = new label();
314                             lbl.name = "dgvcolumns_" + i;
315                             lbl.text = item.headtext;
316                             lbl.font = m_headfont;
317                             lbl.forecolor = m_headtextcolor;
318                             lbl.textalign = contentalignment.middlecenter;
319                             lbl.autosize = false;
320                             lbl.dock = dockstyle.fill;
321                             lbl.mousedown += (a, b) =>
322                             {
323                                 if (headcolumnclickevent != null)
324                                 {
325                                     headcolumnclickevent(a, b);
326                                 }
327                             };
328                             c = lbl;
329                         }
330                         this.pancolumns.controls.add(c, i, 0);
331                     }
332 
333                 }
334             }
335             finally
336             {
337                 controlhelper.freezecontrol(this.panhead, false);
338             }
339         }
340         #endregion
341 
342         /// <summary>
343         /// 功能描述:获取显示个数
344         /// 作  者:hzh
345         /// 创建日期:2019-03-05 10:02:58
346         /// 任务编号:pos
347         /// </summary>
348         /// <returns>返回值</returns>
349         private void resetshowcount()
350         {
351             if (designmode)
352             { return; }
353             showcount = this.panrow.height / (m_rowheight);
354             int intcha = this.panrow.height % (m_rowheight);
355             m_rowheight += intcha / showcount;
356         }
357         #endregion
358 
359         #region 公共函数
360         /// <summary>
361         /// 刷新数据
362         /// </summary>
363         public void reloadsource()
364         {
365             if (designmode)
366             { return; }
367             try
368             {
369                 if (m_columns == null || m_columns.count <= 0)
370                     return;
371 
372                 controlhelper.freezecontrol(this.panrow, true);
373                 this.panrow.controls.clear();
374                 rows = new list<idatagridviewrow>();
375                 if (m_datasource != null)
376                 {
377                     int intindex = 0;
378                     control lastitem = null;
379 
380                     int intsourcecount = 0;
381                     if (m_datasource is datatable)
382                     {
383                         intsourcecount = (m_datasource as datatable).rows.count;
384                     }
385                     else if (typeof(ilist).isassignablefrom(m_datasource.gettype()))
386                     {
387                         intsourcecount = (m_datasource as ilist).count;
388                     }
389 
390                     foreach (control item in this.panrow.controls)
391                     {
392 
393 
394                         if (intindex >= intsourcecount)
395                         {
396                             item.visible = false;
397                         }
398                         else
399                         {
400                             var row = (item as idatagridviewrow);
401                             row.isshowcheckbox = m_isshowcheckbox;
402                             if (m_datasource is datatable)
403                             {
404                                 row.datasource = (m_datasource as datatable).rows[intindex];
405                             }
406                             else
407                             {
408                                 row.datasource = (m_datasource as ilist)[intindex];
409                             }
410                             row.bindingcelldata();
411                             item.height = m_rowheight;
412                             item.visible = true;
413                             item.bringtofront();
414                             if (lastitem == null)
415                                 lastitem = item;
416                             rows.add(row);
417                         }
418                         intindex++;
419                     }
420 
421                     if (intindex < intsourcecount)
422                     {
423                         for (int i = intindex; i < intsourcecount; i++)
424                         {
425                             idatagridviewrow row = (idatagridviewrow)activator.createinstance(m_rowtype);
426                             if (m_datasource is datatable)
427                             {
428                                 row.datasource = (m_datasource as datatable).rows[i];
429                             }
430                             else
431                             {
432                                 row.datasource = (m_datasource as ilist)[i];
433                             }
434                             row.columns = m_columns;
435                             list<control> lstcells = new list<control>();
436                             row.isshowcheckbox = m_isshowcheckbox;
437                             row.reloadcells();
438                             row.bindingcelldata();
439 
440 
441                             control rowcontrol = (row as control);
442                             rowcontrol.height = m_rowheight;
443                             this.panrow.controls.add(rowcontrol);
444                             rowcontrol.dock = dockstyle.top;
445                             row.cellclick += (a, b) => { setselectrow(rowcontrol, b); };
446                             row.checkboxchangeevent += (a, b) => { setselectrow(rowcontrol, b); };
447                             row.sourcechanged += rowsourcechanged;
448                             rowcontrol.bringtofront();
449                             rows.add(row);
450 
451                             if (lastitem == null)
452                                 lastitem = rowcontrol;
453                         }
454                     }
455                     if (lastitem != null && intsourcecount == m_showcount)
456                     {
457                         lastitem.height = this.panrow.height - (m_showcount - 1) * m_rowheight;
458                     }
459                 }
460             }
461             finally
462             {
463                 controlhelper.freezecontrol(this.panrow, false);
464             }
465         }
466 
467 
468         /// <summary>
469         /// 快捷键
470         /// </summary>
471         /// <param name="msg"></param>
472         /// <param name="keydata"></param>
473         /// <returns></returns>
474         protected override bool processcmdkey(ref message msg, keys keydata)
475         {
476             if (keydata == keys.up)
477             {
478                 previous();
479             }
480             else if (keydata == keys.down)
481             {
482                 next();
483             }
484             else if (keydata == keys.home)
485             {
486                 first();
487             }
488             else if (keydata == keys.end)
489             {
490                 end();
491             }
492             return base.processcmdkey(ref msg, keydata);
493         }
494         /// <summary>
495         /// 选中第一个
496         /// </summary>
497         public void first()
498         {
499             if (rows == null || rows.count <= 0)
500                 return;
501             control c = null;
502             c = (rows[0] as control);
503             setselectrow(c, new datagridvieweventargs() { rowindex = 0 });
504         }
505         /// <summary>
506         /// 选中上一个
507         /// </summary>
508         public void previous()
509         {
510             if (rows == null || rows.count <= 0)
511                 return;
512             control c = null;
513 
514             int index = rows.indexof(m_selectrow);
515             if (index - 1 >= 0)
516             {
517                 c = (rows[index - 1] as control);
518                 setselectrow(c, new datagridvieweventargs() { rowindex = index - 1 });
519             }
520         }
521         /// <summary>
522         /// 选中下一个
523         /// </summary>
524         public void next()
525         {
526             if (rows == null || rows.count <= 0)
527                 return;
528             control c = null;
529 
530             int index = rows.indexof(m_selectrow);
531             if (index + 1 < rows.count)
532             {
533                 c = (rows[index + 1] as control);
534                 setselectrow(c, new datagridvieweventargs() { rowindex = index + 1 });
535             }
536         }
537         /// <summary>
538         /// 选中最后一个
539         /// </summary>
540         public void end()
541         {
542             if (rows == null || rows.count <= 0)
543                 return;
544             control c = null;
545             c = (rows[rows.count - 1] as control);
546             setselectrow(c, new datagridvieweventargs() { rowindex = rows.count - 1 });
547         }
548 
549         #endregion
550 
551         #region 事件
552         void rowsourcechanged(object sender, datagridvieweventargs e)
553         {
554             if (sourcechanged != null)
555                 sourcechanged(sender, e);
556         }
557         private void setselectrow(control item, datagridvieweventargs e)
558         {
559             try
560             {
561                 controlhelper.freezecontrol(this, true);
562                 if (item == null)
563                     return;
564                 if (item.visible == false)
565                     return;
566                 this.findform().activecontrol = this;
567                 this.findform().activecontrol = item;
568                 if (m_selectrow != null)
569                 {
570                     if (m_selectrow == item)
571                         return;
572                     m_selectrow.setselect(false);
573                 }
574                 m_selectrow = item as idatagridviewrow;
575                 m_selectrow.setselect(true);
576                 if (itemclick != null)
577                 {
578                     itemclick(item, e);
579                 }
580                 if (this.panrow.controls.count > 0)
581                 {
582                     if (item.location.y < 0)
583                     {
584                         this.panrow.autoscrollposition = new point(0, math.abs(this.panrow.controls[this.panrow.controls.count - 1].location.y) + item.location.y);
585                     }
586                     else if (item.location.y + m_rowheight > this.panrow.height)
587                     {
588                         this.panrow.autoscrollposition = new point(0, math.abs(this.panrow.autoscrollposition.y) + item.location.y - this.panrow.height + m_rowheight);
589                     }
590                 }
591             }
592             finally
593             {
594                 controlhelper.freezecontrol(this, false);
595             }
596         }
597         private void ucdatagridview_resize(object sender, eventargs e)
598         {
599             resetshowcount();
600             reloadsource();
601         }
602         #endregion
603     }
604 }
  1 namespace hzh_controls.controls
  2 {
  3     partial class ucdatagridview
  4     {
  5         /// <summary> 
  6         /// 必需的设计器变量。
  7         /// </summary>
  8         private system.componentmodel.icontainer components = null;
  9 
 10         /// <summary> 
 11         /// 清理所有正在使用的资源。
 12         /// </summary>
 13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
 14         protected override void dispose(bool disposing)
 15         {
 16             if (disposing && (components != null))
 17             {
 18                 components.dispose();
 19             }
 20             base.dispose(disposing);
 21         }
 22 
 23         #region 组件设计器生成的代码
 24 
 25         /// <summary> 
 26         /// 设计器支持所需的方法 - 不要
 27         /// 使用代码编辑器修改此方法的内容。
 28         /// </summary>
 29         private void initializecomponent()
 30         {
 31             this.panhead = new system.windows.forms.panel();
 32             this.pancolumns = new system.windows.forms.tablelayoutpanel();
 33             this.ucsplitline_h1 = new hzh_controls.controls.ucsplitline_h();
 34             this.panrow = new system.windows.forms.panel();
 35             this.panpage = new system.windows.forms.panel();
 36             this.panhead.suspendlayout();
 37             this.suspendlayout();
 38             // 
 39             // panhead
 40             // 
 41             this.panhead.controls.add(this.pancolumns);
 42             this.panhead.controls.add(this.ucsplitline_h1);
 43             this.panhead.dock = system.windows.forms.dockstyle.top;
 44             this.panhead.location = new system.drawing.point(0, 0);
 45             this.panhead.name = "panhead";
 46             this.panhead.size = new system.drawing.size(1061, 40);
 47             this.panhead.tabindex = 0;
 48             // 
 49             // pancolumns
 50             // 
 51             this.pancolumns.columncount = 1;
 52             this.pancolumns.columnstyles.add(new system.windows.forms.columnstyle(system.windows.forms.sizetype.percent, 100f));
 53             this.pancolumns.dock = system.windows.forms.dockstyle.fill;
 54             this.pancolumns.location = new system.drawing.point(0, 0);
 55             this.pancolumns.name = "pancolumns";
 56             this.pancolumns.rowcount = 1;
 57             this.pancolumns.rowstyles.add(new system.windows.forms.rowstyle(system.windows.forms.sizetype.percent, 100f));
 58             this.pancolumns.rowstyles.add(new system.windows.forms.rowstyle(system.windows.forms.sizetype.absolute, 20f));
 59             this.pancolumns.size = new system.drawing.size(1061, 39);
 60             this.pancolumns.tabindex = 1;
 61             // 
 62             // ucsplitline_h1
 63             // 
 64             this.ucsplitline_h1.backcolor = system.drawing.color.fromargb(((int)(((byte)(232)))), ((int)(((byte)(232)))), ((int)(((byte)(232)))));
 65             this.ucsplitline_h1.dock = system.windows.forms.dockstyle.bottom;
 66             this.ucsplitline_h1.location = new system.drawing.point(0, 39);
 67             this.ucsplitline_h1.name = "ucsplitline_h1";
 68             this.ucsplitline_h1.size = new system.drawing.size(1061, 1);
 69             this.ucsplitline_h1.tabindex = 0;
 70             this.ucsplitline_h1.tabstop = false;
 71             // 
 72             // panrow
 73             // 
 74             this.panrow.autoscroll = true;
 75             this.panrow.dock = system.windows.forms.dockstyle.fill;
 76             this.panrow.location = new system.drawing.point(0, 40);
 77             this.panrow.name = "panrow";
 78             this.panrow.size = new system.drawing.size(1061, 475);
 79             this.panrow.tabindex = 1;
 80             // 
 81             // panpage
 82             // 
 83             this.panpage.dock = system.windows.forms.dockstyle.bottom;
 84             this.panpage.location = new system.drawing.point(0, 515);
 85             this.panpage.name = "panpage";
 86             this.panpage.size = new system.drawing.size(1061, 50);
 87             this.panpage.tabindex = 0;
 88             this.panpage.visible = false;
 89             // 
 90             // ucdatagridview
 91             // 
 92             this.autoscalemode = system.windows.forms.autoscalemode.none;
 93             this.backcolor = system.drawing.color.white;
 94             this.controls.add(this.panrow);
 95             this.controls.add(this.panpage);
 96             this.controls.add(this.panhead);
 97             this.name = "ucdatagridview";
 98             this.size = new system.drawing.size(1061, 565);
 99             this.resize += new system.eventhandler(this.ucdatagridview_resize);
100             this.panhead.resumelayout(false);
101             this.resumelayout(false);
102 
103         }
104 
105         #endregion
106 
107         private system.windows.forms.panel panhead;
108         private system.windows.forms.tablelayoutpanel pancolumns;
109         private ucsplitline_h ucsplitline_h1;
110         private system.windows.forms.panel panrow;
111         private system.windows.forms.panel panpage;
112 
113     }
114 }

如果你仔细看,你会发现行我用了类型进行传入,当你需要更丰富的行内容的时候,可以自定义行控件,然后通过rowtype属性传入

分页控件我使用了分页控件基类ucpagercontrolbase,这样做的好处就是你同样可以扩展分页控件

用处及效果

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

调用示例

 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();

如果使用分页控件,则将数据源指定给分页控件,否则直接指定给表格控件数据源

最后的话

如果你喜欢的话,请到  点个星 星吧