当前位置: 移动技术网 > IT编程>开发语言>.net > WinForm中DataGridView折叠控件【超好看】

WinForm中DataGridView折叠控件【超好看】

2017年12月12日  | 移动技术网IT编程  | 我要评论

电磁炉修理,赵泓霖,左手仙缘txt下载

刚到一家新公司,领导下发任务要用cs系统做一个表格折叠显示,这真是把我难倒了,自己工作6年一直以来都是做bs的系统。这如果在bs里面那太简单了,jqgrid默认都自带,可是datagridview不支持折叠啊。自己一点经验没有,怎么办呢?于是上网搜了相关视频,资料,开始学习起来。最后借鉴源码封了这么一个东西,发出来分享下,也能让自己加深印象。

首先不多说,上图。如果大家感谢还不错,请继续往下阅读:


大概的效果就是这样。

上代码。

1、首先重写datagridview,代码如下:

public class mastercontrol : datagridview
{
#region 字段
private list<int> rowcurrent = new list<int>();
internal static int rowdefaultheight = ;
internal static int rowexpandedheight = ;
internal static int rowdefaultdivider = ;
internal static int rowexpandeddivider = - ;
internal static int rowdividermargin = ;
internal static bool collapserow;
     //detailcontrol变量作为一个容器用来保存子表格
public detailcontrol childview = new detailcontrol() { visible = false }; // vbconversions note: initial value cannot be assigned here since it is non-static. assignment has been moved to the class constructors.
//
internal system.windows.forms.imagelist rowheadericonlist;
private system.componentmodel.container components = null;
//
dataset _cdataset;
string _foreignkey;
string _primarykey;
string _filterformat;
private controltype econtroltype;
public int expandrowindex = ;
#endregion
#region 构造函数
/// <summary>
/// 通过传递过来的枚举判断是两级还是三级展开,表的对应关系通过relations来读取
/// 所以调用此构造函数的时候必须要讲relations设置正确,才能正确显示层级关系。
/// odataset.relations.add("", odataset.tables["t"].columns["menu_id"], odataset.tables["t"].columns["menu_id"]);
/// odataset.relations.add("", odataset.tables["t"].columns["menu_name"], odataset.tables["t"].columns["menu_name"]);
/// 这两次add的顺序不能颠倒,必须先添加一、二级的表关联,再添加二、三级的表关联
/// </summary>
/// <param name="cdataset">数据源dataset,里面还有各个表的对应关系</param>
/// <param name="econtroltype">枚举类型</param>
public mastercontrol(dataset cdataset, controltype econtroltype)
{
setmastercontrol(cdataset, econtroltype); 
}
/// <summary>
/// 第二种使用方法
/// </summary>
/// <param name="lstdata">折叠控件第一层的集合</param>
/// <param name="lstdata">折叠控件第二层的集合</param>
/// <param name="lstdata">折叠控件第三层的集合</param>
/// <param name="dicrelatekey">第一二层之间对应主外键</param>
/// <param name="dicrelatekey">第二三层之间对应主外键</param>
/// <param name="econtroltype">枚举类型</param>
public mastercontrol(object lstdata, object lstdata, 
object lstdata, dictionary<string, string> dicrelatekey, 
dictionary<string ,string>dicrelatekey, controltype econtroltype)
{
var odataset = new dataset();
try
{
var otable = new datatable();
otable = fill(lstdata);
otable.tablename = "t";
var otable = fill(lstdata);
otable.tablename = "t";
if (lstdata == null || dicrelatekey == null || dicrelatekey.keys.count <= )
{
odataset.tables.addrange(new datatable[] { otable, otable });
odataset.relations.add("", odataset.tables["t"].columns[dicrelatekey.keys.firstordefault()], odataset.tables["t"].columns[dicrelatekey.values.firstordefault()]);
}
else
{
var otable = fill(lstdata);
otable.tablename = "t";
odataset.tables.addrange(new datatable[] { otable, otable, otable });
//这是对应关系的时候主键必须唯一
odataset.relations.add("", odataset.tables["t"].columns[dicrelatekey.keys.firstordefault()], odataset.tables["t"].columns[dicrelatekey.values.firstordefault()]);
odataset.relations.add("", odataset.tables["t"].columns[dicrelatekey.keys.firstordefault()], odataset.tables["t"].columns[dicrelatekey.values.firstordefault()]);
}
}
catch
{
odataset = new dataset();
}
setmastercontrol(odataset, econtroltype);
}
/// <summary>
/// 控件初始化
/// </summary>
private void initializecomponent()
{
this.components = new system.componentmodel.container();
base.rowheadermouseclick += new system.windows.forms.datagridviewcellmouseeventhandler(mastercontrol_rowheadermouseclick);
base.rowpostpaint += new system.windows.forms.datagridviewrowpostpainteventhandler(mastercontrol_rowpostpaint);
base.scroll += new system.windows.forms.scrolleventhandler(mastercontrol_scroll);
base.selectionchanged += new system.eventhandler(mastercontrol_selectionchanged);
system.componentmodel.componentresourcemanager resources = new system.componentmodel.componentresourcemanager(typeof(mastercontrol));
this.rowheadericonlist = new system.windows.forms.imagelist(this.components);
((system.componentmodel.isupportinitialize)this).begininit();
this.suspendlayout();
//
//rowheadericonlist
//
this.rowheadericonlist.imagestream = (system.windows.forms.imageliststreamer)(resources.getobject("rowheadericonlist.imagestream"));
this.rowheadericonlist.transparentcolor = system.drawing.color.transparent;
this.rowheadericonlist.images.setkeyname(, "expand.png");
this.rowheadericonlist.images.setkeyname(, "collapse.png");
//
//mastercontrol
//
((system.componentmodel.isupportinitialize)this).endinit();
this.resumelayout(false);
}
#endregion
#region 数据绑定
/// <summary>
/// 设置表之间的主外键关联
/// </summary>
/// <param name="tablename">datatable的表名称</param>
/// <param name="foreignkey">外键</param>
public void setparentsource(string tablename, string primarykey, string foreignkey)
{
this.datasource = new dataview(_cdataset.tables[tablename]);
cmodule.setgridrowheader(this);
_foreignkey = foreignkey;
_primarykey = primarykey;
if (_cdataset.tables[tablename].columns[primarykey].gettype().tostring() == typeof(int).tostring()
|| _cdataset.tables[tablename].columns[primarykey].gettype().tostring() == typeof(double).tostring()
|| _cdataset.tables[tablename].columns[primarykey].gettype().tostring() == typeof(decimal).tostring())
{
_filterformat = foreignkey + "={}";
}
else
{
_filterformat = foreignkey + "=\'{}\'";
}
}
#endregion
#region 事件
//控件的行头点击事件
private void mastercontrol_rowheadermouseclick(object sender, datagridviewcellmouseeventargs e)
{
try
{
rectangle rect = new rectangle(system.convert.toint((double)(rowdefaultheight - ) / ), system.convert.toint((double)(rowdefaultheight - ) / ), , );
if (rect.contains(e.location))
{
//缩起
if (rowcurrent.contains(e.rowindex))
{
rowcurrent.clear();
this.rows[e.rowindex].height = rowdefaultheight;
this.rows[e.rowindex].dividerheight = rowdefaultdivider;
this.clearselection();
collapserow = true;
this.rows[e.rowindex].selected = true;
if (econtroltype == controltype.middle)
{
var oparent = ((mastercontrol)this.parent.parent);
oparent.rows[oparent.expandrowindex].height = rowdefaultheight * (this.rows.count + );
oparent.rows[oparent.expandrowindex].dividerheight = rowdefaultheight * (this.rows.count + );
if (oparent.rows[oparent.expandrowindex].height > )
{
oparent.rows[oparent.expandrowindex].height = ;
oparent.rows[oparent.expandrowindex].height = ;
}
}
}
//展开
else
{
if (!(rowcurrent.count == ))
{
var erow = rowcurrent[];
rowcurrent.clear();
this.rows[erow].height = rowdefaultheight;
this.rows[erow].dividerheight = rowdefaultdivider;
this.clearselection();
collapserow = true;
this.rows[erow].selected = true;
}
rowcurrent.add(e.rowindex);
this.clearselection();
collapserow = true;
this.rows[e.rowindex].selected = true;
this.expandrowindex = e.rowindex;
this.rows[e.rowindex].height = + rowdefaultheight * (((dataview)(childview.childgrid[].datasource)).count + );
this.rows[e.rowindex].dividerheight = + rowdefaultheight * (((dataview)(childview.childgrid[].datasource)).count);
//设置一个最大高度
if (this.rows[e.rowindex].height > )
{
this.rows[e.rowindex].height = ;
this.rows[e.rowindex].dividerheight = ;
}
if (econtroltype == controltype.middle)
{
if (this.parent.parent.gettype() != typeof(mastercontrol))
return;
var oparent = ((mastercontrol)this.parent.parent);
oparent.rows[oparent.expandrowindex].height = this.rows[e.rowindex].height + rowdefaultheight * (this.rows.count + );
oparent.rows[oparent.expandrowindex].dividerheight = this.rows[e.rowindex].dividerheight + rowdefaultheight * (this.rows.count + );
if (oparent.rows[oparent.expandrowindex].height > )
{
oparent.rows[oparent.expandrowindex].height = ;
oparent.rows[oparent.expandrowindex].height = ;
}
}
//if (econtroltype == controltype.outside)
//{
// //setcontrol(this);
//}
//this.rows[e.rowindex].height = rowexpandedheight;
//this.rows[e.rowindex].dividerheight = rowexpandeddivider;
}
//this.clearselection();
//collapserow = true;
//this.rows[e.rowindex].selected = true;
}
else
{
collapserow = false;
}
}
catch (exception ex)
{
}
}
//控件的行重绘事件
private void mastercontrol_rowpostpaint(object obj_sender, datagridviewrowpostpainteventargs e)
{
try
{
var sender = (datagridview)obj_sender;
//set childview control
var rect = new rectangle((int)(e.rowbounds.x + ((double)(rowdefaultheight - ) / )), (int)(e.rowbounds.y + ((double)(rowdefaultheight - ) / )), , );
if (collapserow)
{
if (this.rowcurrent.contains(e.rowindex))
{
#region 更改点开后背景色 刘金龙
var rect = new rectangle(e.rowbounds.x, e.rowbounds.y + rowdefaultheight, e.rowbounds.width, e.rowbounds.height - rowdefaultheight);
using (brush b = new solidbrush(color.fromargb(, , )))
{
e.graphics.fillrectangle(b, rect);
} 
#endregion
sender.rows[e.rowindex].dividerheight = sender.rows[e.rowindex].height - rowdefaultheight;
e.graphics.drawimage(rowheadericonlist.images[(int)rowheadericons.collapse], rect);
childview.location = new point(e.rowbounds.left + sender.rowheaderswidth, e.rowbounds.top + rowdefaultheight + );
childview.width = e.rowbounds.right - sender.rowheaderswidth;
childview.height = system.convert.toint(sender.rows[e.rowindex].dividerheight - );
childview.visible = true;
}
else
{
childview.visible = false;
e.graphics.drawimage(rowheadericonlist.images[(int)rowheadericons.expand], rect);
}
collapserow = false;
}
else
{
if (this.rowcurrent.contains(e.rowindex))
{
#region 更改点开后背景色 刘金龙
var rect = new rectangle(e.rowbounds.x, e.rowbounds.y + rowdefaultheight, e.rowbounds.width, e.rowbounds.height - rowdefaultheight);
using (brush b = new solidbrush(color.fromargb(,,)))
{
e.graphics.fillrectangle(b, rect);
} 
#endregion
sender.rows[e.rowindex].dividerheight = sender.rows[e.rowindex].height - rowdefaultheight;
e.graphics.drawimage(rowheadericonlist.images[(int)rowheadericons.collapse], rect);
childview.location = new point(e.rowbounds.left + sender.rowheaderswidth, e.rowbounds.top + rowdefaultheight + );
childview.width = e.rowbounds.right - sender.rowheaderswidth;
childview.height = system.convert.toint(sender.rows[e.rowindex].dividerheight - );
childview.visible = true;
}
else
{
childview.visible = false;
e.graphics.drawimage(rowheadericonlist.images[(int)rowheadericons.expand], rect);
}
}
cmodule.rowpostpaint_headercount(sender, e);
}
catch
{
}
}
//控件的滚动条滚动事件
private void mastercontrol_scroll(object sender, scrolleventargs e)
{
try
{
if (!(rowcurrent.count == ))
{
collapserow = true;
this.clearselection();
this.rows[rowcurrent[]].selected = true;
}
}
catch
{
}
}
//控件的单元格选择事件
private void mastercontrol_selectionchanged(object sender, eventargs e)
{
try
{
if (!(this.rowcount == ))
{
if (rowcurrent.contains(this.currentrow.index))
{
foreach (datagridview cgrid in childview.childgrid)
{
((dataview)cgrid.datasource).rowfilter = string.format(_filterformat, this[_primarykey, this.currentrow.index].value);
}
}
}
}
catch
{
}
}
#endregion
#region private
//设置构造函数的参数
private void setmastercontrol(dataset cdataset, controltype econtroltype)
{
//.控件初始化赋值
this.controls.add(childview);
initializecomponent();
_cdataset = cdataset;
childview._cdataset = cdataset;
cmodule.applygridtheme(this);
dock = dockstyle.fill;
econtroltype = econtroltype;
this.allowusertoaddrows = false;
//.通过读取dataset里面的relations得到表的关联关系
if (cdataset.relations.count <= )
{
return;
}
datarelation orelates;
if (econtroltype == controltype.outside)
{
orelates = cdataset.relations[];
childview.add(orelates.parenttable.tablename, orelates.parentcolumns[].columnname, orelates.childcolumns[].columnname);
}
else if (econtroltype == controltype.middle)
{
orelates = cdataset.relations[cdataset.relations.count - ];
childview.add(orelates.childtable.tablename);
}
//.设置主外键对应关系
orelates = cdataset.relations[];
//主表里面的值,副表里面的过滤字段
setparentsource(orelates.parenttable.tablename,orelates.parentcolumns[].columnname, orelates.childcolumns[].columnname);
}
private void setcontrol(mastercontrol ogrid)
{
ogrid.childview.removecontrol();
//ogrid.childview.controls.removebykey("childrenmaster");
//
//var orelates = _cdataset.relations[];
//ogrid.childview.add(orelates.parenttable.tablename, orelates.childcolumns[].columnname);
//foreach (var ogridcontrol in ogrid.controls)
//{
// if (ogridcontrol.gettype() != typeof(detailcontrol))
// {
// continue;
// }
// var detailcontrol =(detailcontrol)ogridcontrol;
// foreach (var odetailcontrol in detailcontrol.controls)
// {
// if (odetailcontrol.gettype() != typeof(mastercontrol))
// {
// continue;
// }
// var omastercontrol = (mastercontrol)odetailcontrol;
// foreach (var omastercontrol in omastercontrol.controls)
// {
// if (omastercontrol.gettype() == typeof(detailcontrol))
// {
// ((detailcontrol)omastercontrol).visible = false;
// return;
// }
// }
// }
//}
}
//将list集合转换成datatable
private datatable fill(object obj)
{
if(!(obj is ilist))
{
return null;
}
var objlist = obj as ilist;
if (objlist == null || objlist.count <= )
{
return null;
}
var ttype = objlist[];
datatable dt = new datatable(ttype.gettype().name);
datacolumn column;
datarow row;
system.reflection.propertyinfo[] mypropertyinfo = ttype.gettype().getproperties(bindingflags.public | bindingflags.instance);
foreach (var t in objlist)
{
if (t == null)
{
continue;
}
row = dt.newrow();
for (int i = , j = mypropertyinfo.length; i < j; i++)
{
system.reflection.propertyinfo pi = mypropertyinfo[i];
string name = pi.name;
if (dt.columns[name] == null)
{
column = new datacolumn(name, pi.propertytype);
dt.columns.add(column);
}
row[name] = pi.getvalue(t, null);
}
dt.rows.add(row);
}
return dt;
}
#endregion
} 

2、detailcontrol变量作为一个容器用来保存子表格

代码如下:

public class detailcontrol : ewin.client.frame.controls.ewinpanel
{
#region 字段
public list<datagridview> childgrid = new list<datagridview>();
public dataset _cdataset;
#endregion
#region 方法
public void add(string tablename, string strprimarykey, string strforeignkey)
{
//tabpage tpage = new tabpage() { text = pagecaption };
//this.controls.add(tpage);
var newgrid = new mastercontrol(_cdataset, controltype.middle) { dock = dockstyle.fill, datasource = new dataview(_cdataset.tables[tablename]) };
newgrid.setparentsource(tablename, strprimarykey, strforeignkey);//设置主外键
//newgrid.name = "childrenmaster";
//tpage.controls.add(newgrid);
this.controls.add(newgrid);
//this.borderstyle = borderstyle.fixedsingle;
cmodule.applygridtheme(newgrid);
cmodule.setgridrowheader(newgrid);
newgrid.rowpostpaint += cmodule.rowpostpaint_headercount;
childgrid.add(newgrid);
}
public void add(string tablename)
{
//tabpage tpage = new tabpage() { text = pagecaption };
//this.controls.add(tpage);
datagridview newgrid = new ewin.client.frame.controls.ewingrid() { dock = dockstyle.fill, datasource = new dataview(_cdataset.tables[tablename]) };
newgrid.allowusertoaddrows = false;
//tpage.controls.add(newgrid);
this.controls.add(newgrid);
cmodule.applygridtheme(newgrid);
cmodule.setgridrowheader(newgrid);
newgrid.rowpostpaint += cmodule.rowpostpaint_headercount;
childgrid.add(newgrid);
}
public void removecontrol()
{
this.controls.remove(childgrid[]);
childgrid.clear();
}
#endregion
} 

3、cmodule.cs用来设置样式

namespace ewin.client.frame.ucgrid
{
/// <summary>
/// 折叠控件样式以及行数操作类
/// </summary>
sealed class cmodule
{
#region customgrid
static system.windows.forms.datagridviewcellstyle datecellstyle = new system.windows.forms.datagridviewcellstyle { alignment = datagridviewcontentalignment.middleright };
static system.windows.forms.datagridviewcellstyle amountcellstyle = new system.windows.forms.datagridviewcellstyle { alignment = datagridviewcontentalignment.middleright, format = "n" };
static system.windows.forms.datagridviewcellstyle gridcellstyle = new system.windows.forms.datagridviewcellstyle
{
alignment = system.windows.forms.datagridviewcontentalignment.middleleft,
backcolor = system.drawing.color.fromargb(system.convert.toint(system.convert.tobyte()), system.convert.toint(system.convert.tobyte()), system.convert.toint(system.convert.tobyte())),
font = new system.drawing.font("segoe ui", (float)(.f), system.drawing.fontstyle.regular, system.drawing.graphicsunit.point, system.convert.tobyte()),
forecolor = system.drawing.systemcolors.controllightlight,
selectionbackcolor = system.drawing.systemcolors.highlight,
selectionforecolor = system.drawing.systemcolors.highlighttext,
wrapmode = system.windows.forms.datagridviewtristate.true
};
static system.windows.forms.datagridviewcellstyle gridcellstyle = new system.windows.forms.datagridviewcellstyle
{
alignment = system.windows.forms.datagridviewcontentalignment.middleleft,
backcolor = system.drawing.systemcolors.controllightlight,
font = new system.drawing.font("segoe ui", (float)(.f), system.drawing.fontstyle.regular, system.drawing.graphicsunit.point, system.convert.tobyte()),
forecolor = system.drawing.systemcolors.controltext,
selectionbackcolor = system.drawing.color.fromargb(system.convert.toint(system.convert.tobyte()), system.convert.toint(system.convert.tobyte()), system.convert.toint(system.convert.tobyte())),
selectionforecolor = system.drawing.systemcolors.highlighttext,
wrapmode = system.windows.forms.datagridviewtristate.false
};
static system.windows.forms.datagridviewcellstyle gridcellstyle = new system.windows.forms.datagridviewcellstyle
{
alignment = system.windows.forms.datagridviewcontentalignment.middleleft,
backcolor = system.drawing.color.whitesmoke,
font = new system.drawing.font("segoe ui", (float)(.f), system.drawing.fontstyle.regular, system.drawing.graphicsunit.point, system.convert.tobyte()),
forecolor = system.drawing.systemcolors.windowtext,
selectionbackcolor = system.drawing.color.fromargb(system.convert.toint(system.convert.tobyte()), system.convert.toint(system.convert.tobyte()), system.convert.toint(system.convert.tobyte())),
selectionforecolor = system.drawing.systemcolors.highlighttext,
wrapmode = system.windows.forms.datagridviewtristate.true
};
//设置表格的主题样式
static public void applygridtheme(datagridview grid)
{
grid.allowusertoaddrows = false;
grid.allowusertodeleterows = false;
grid.backgroundcolor = system.drawing.systemcolors.window;
grid.borderstyle = system.windows.forms.borderstyle.none;
grid.columnheadersborderstyle = system.windows.forms.datagridviewheaderborderstyle.single;
grid.columnheadersdefaultcellstyle = gridcellstyle;
grid.columnheadersheight = ;
grid.columnheadersheightsizemode = system.windows.forms.datagridviewcolumnheadersheightsizemode.disableresizing;
grid.defaultcellstyle = gridcellstyle;
grid.enableheadersvisualstyles = false;
grid.gridcolor = system.drawing.systemcolors.gradientinactivecaption;
//grid.readonly = true;
grid.rowheadersvisible = true;
grid.rowheadersborderstyle = system.windows.forms.datagridviewheaderborderstyle.single;
grid.rowheadersdefaultcellstyle = gridcellstyle;
grid.font = gridcellstyle.font;
}
//设置表格单元格样式
static public void setgridrowheader(datagridview dgv, bool hsize = false)
{
dgv.topleftheadercell.value = "no ";
dgv.topleftheadercell.style.alignment = datagridviewcontentalignment.middlecenter;
dgv.autoresizerowheaderswidth(datagridviewrowheaderswidthsizemode.autosizetodisplayedheaders);
foreach (datagridviewcolumn ccol in dgv.columns)
{
if (ccol.valuetype.tostring() == typeof(datetime).tostring())
{
ccol.defaultcellstyle = datecellstyle;
}
else if (ccol.valuetype.tostring() == typeof(decimal).tostring() || ccol.valuetype.tostring() == typeof(double).tostring())
{
ccol.defaultcellstyle = amountcellstyle;
}
}
if (hsize)
{
dgv.rowheaderswidth = dgv.rowheaderswidth + ;
}
dgv.autoresizecolumns();
}
//设置表格的行号
static public void rowpostpaint_headercount(object obj_sender, datagridviewrowpostpainteventargs e)
{
try
{
var sender = (datagridview)obj_sender;
//set rowheader count
datagridview grid = (datagridview)sender;
string rowidx = system.convert.tostring((e.rowindex + ).tostring());
var centerformat = new stringformat();
centerformat.alignment = stringalignment.center;
centerformat.linealignment = stringalignment.center;
rectangle headerbounds = new rectangle(e.rowbounds.left, e.rowbounds.top,
grid.rowheaderswidth, e.rowbounds.height - sender.rows[e.rowindex].dividerheight);
e.graphics.drawstring(rowidx, grid.font, systembrushes.controltext,
headerbounds, centerformat);
}
catch (exception ex)
{
}
}
#endregion
}
/// <summary>
/// 控件类型,是最外层的表格还是中间层的表格
/// </summary>
public enum controltype
{
outside = ,
middle = 
}
/// <summary>
/// 展开图标
/// </summary>
public enum rowheadericons
{
expand = ,
collapse = 
}
}

4、from页面调用

#region 使用方法一

//var odataset = getdataset();
//
//masterdetail = new mastercontrol(odataset, controltype.outside); 
#endregion

#region 使用方法二

var dicrelatedata1 = new dictionary<string, string>();
var dicrelatedata2 = new dictionary<string, string>();
dicrelatedata1.add("menu_id","menu_id");//表格一和表格二之间的主外键关系
dicrelatedata2.add("menu_name2","menu_name2");//表格二和表格三之间的主外键关系 
masterdetail = new mastercontrol(getdatasource(), getdatasource2(), getdatasource3(), dicrelatedata1, dicrelatedata2, controltype.outside); #endregion panelview.controls.add(masterdetail); 

昨天应领导要求,折叠控件增加了折叠线的效果,看起来有没有更加像模像样了。~~~

其实就在行重绘事件private void mastercontrol_rowpostpaint(object obj_sender, datagridviewrowpostpainteventargs e)里面增加了如下代码:

using (pen p = new pen(color.ghostwhite))
{
var ihalfwidth = (e.rowbounds.left + sender.rowheaderswidth) / 2;
var opointhlinestart = new point(rect1.x + ihalfwidth, rect1.y);
var opointhlineend = new point(rect1.x + ihalfwidth, rect1.y + rect1.height / 2);
e.graphics.drawline(p, opointhlinestart, opointhlineend);
//折叠线
e.graphics.drawline(p, opointhlineend, new point(opointhlineend.x + ihalfwidth, opointhlineend.y));
}


效果如下:

以上所述是小编给大家介绍的winform中datagridview折叠控件的相关知识,希望对大家有所帮助!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网