设计数据源并绑定字段:
数据源可以是实现下列接口之一的任何类型:
- ilist 接口,包括一维数组。list<t>等!
- ilistsource 接口,例如,datatable 和 dataset 类。
- ibindinglist 接口,例如,bindinglist 类。
- ibindinglistview 接口,例如,bindingsource 类。
修改也是同步的
datatable datatable = new datatable(); datatable.columns.add("name", system.type.gettype("system.string")); datatable.columns.add("sex", system.type.gettype("system.string")); datatable.columns.add("age", system.type.gettype("system.string")); datarow row = dt.newrow(); ; row["name"] = "mathilda"; row["sex"] = "loli"; row["age"] = "12"; datatable.rows.add(row); // 绑定字段 gridview1.columns[1].fieldname = "sex"; gridview1.columns[2].fieldname = "age"; gridview1.columns[0].fieldname = "name"; gridcontrol1.datasource = datatable;
根据数据源自动产生列
gridview2.populatecolumns();
表格数据与数据源的数据同步
xtragrid与windows自带的datagridview在数据源方面不同的是,对grid里的数据进行任何改动(增、删、改)之后,原本的数据源也相应的改动。通过下面例子可以得出此结论,在窗体添加删,改两个按钮并绑定下面相应的事件。
/// <summary> /// 更改 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btedit_click(object sender, eventargs e) { person p = (person)gridview1.getrow(gridview1.focusedrowhandle); } /// <summary> /// 删除 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btdelete_click(object sender, eventargs e) { if (gridview1.selectedrowscount != 0) gridview1.deleteselectedrows(); messagebox.show(people.count.tostring()); }
只要对grid的数据经过改动之后,单击相应的按钮就可以查看数据源的信息。
新增一条记录,添加行
(1)、gridview.addnewrow()、gridview.updatecurrentrow()
数据源datasource如果是datatable可以用addnewrow方法,然后updatecurrentrow。
但是如果datasource的来源是list<t>,用addnewrow是不起作用的,这时候需要将list<t>转换为bindinglist<t>,才可以采用addnewrow。
然后使用gridview.updatecurrentrow()将更改同步到数据源datatable或bindinglist中。
(2)、实现 gridview_initnewrow 事件
删除选中行
删除选中行, 可通过deleteselectedrows()方法,
然后使用gridview.updatecurrentrow()将更改同步到数据源datatable或bindinglist中。
具体示例代码如下:
if (gridview1.selectedrowscount > 0) { gridview1.deleteselectedrows(); gridview.updatecurrentrow() }
获取选定行,指定列单元格的内容
gridview1.getrowcellvalue(prows[0], columname).tostring ();
选择某行后获取当前表格数据:
this.textbox1.text = gridview2.getdatarow(e.rowhandle)["列名"].tostring();
get/set 单元格的值
通过调用getrowcellvalue获取单元格的值。
public override object getrowcellvalue(int rowhandle, gridcolumn column);
rowhandle是行的索引,column列的对象。
通过调用setrowcellvalue设置单元格的值
public void setrowcellvalue(int rowhandle, gridcolumn column, object _value);
rowhandle是行的索引,column列的对象。_value是单元格新的值。
以peoplelist为例
int englishs=convert.todouble(0,gridview1.columns["english"])+60; setrowcellvalue(0,gridview1.columns["english"],englishs);
在xtragrid有另一种方式,就是直接设置数据源的值。对于上面这个例子,直接找到grid里第一行数据对应的person对象,设置它的english值。
选中行改变绑定行数据到对应控件中
1、判断是否有focused行
if (gridview1.isvalidrowhandle(gridview1.focusedrowhandle))
2、获取focused行
1、绑定的是数据行:
datarow row = gridview1.getfocuseddatarow();
2、绑定的是实体:
**entity entity = gridview1.getfocusedrow() as **entity;
3、获取focused行单元格的值
string code = gridview1.getfocusedrowcellvalue("code").tostring(); string code = gridview1.getrowcellvalue(e.focusedrowhandle, "code")
focusedrowchanged事件:
if (bandedgridview1.getfocuseddatarow() == null) return;//判断当前选中行是否为null //返回值 var columnvalue= bandedgridview1.getfocusedrowcellvalue("绑定列字段名称").tostring();
动态添加列
// 动态添加列 devexpress.xtragrid.columns.gridcolumn col1 = new devexpress.xtragrid.columns.gridcolumn(); col1.fieldname = "name"; col1.caption = "名字"; col1.visible = false; col1.visibleindex = gvcountry.columns.count; gvcountry.columns.add(col1);
添加非绑定列
下面的例子主要演示如何为gird网格添加一个非绑定列,从而显示根据 quantity*unitprice*(1-discount)公式计算出来的每个订单的金额。
private void form1_load(object sender, system.eventargs e) { // ... gridcontrol1.forceinitialize(); // create an unbound column. gridcolumn unbcolumn = gridview1.columns.addfield("total"); unbcolumn.visibleindex = gridview1.columns.count; unbcolumn.unboundtype = devexpress.data.unboundcolumntype.decimal; // disable editing. unbcolumn.optionscolumn.allowedit = false; // specify format settings. unbcolumn.displayformat.formattype = devexpress.utils.formattype.numeric; unbcolumn.displayformat.formatstring = "c"; // customize the appearance settings. unbcolumn.appearancecell.backcolor = color.lemonchiffon; } // returns the total amount for a specific row. decimal gettotalvalue(int listsourcerowindex) { datarow row = nwinddataset.tables["order details"].rows[listsourcerowindex]; decimal unitprice = convert.todecimal(row["unitprice"]); decimal quantity = convert.todecimal(row["quantity"]); decimal discount = convert.todecimal(row["discount"]); return unitprice * quantity * (1 - discount); } // provides data for the total column. private void gridview1_customunboundcolumndata(object sender, customcolumndataeventargs e) { if (e.column.fieldname == "total" && e.isgetdata) e.value = gettotalvalue(e.listsourcerowindex); }
编辑器
xtragrid提供了多种编辑器。这些能够在grid/cardview/bandedview中使用。在属性编辑器中的in-place editor repository可以对编辑器进行管理。在columns的columnedit中选择该列使用哪个编辑器。
也可以通过代码实现:
repositoryitemcombobox repositoryitemcombobox_abc=new repositoryitemcombobox(); // // 对编辑器进行设置 // this.gridcolumn1.columnedit = repositoryitemcombobox_abc; //在需要的列里使用定义好的编辑器
添加按钮列
把列的columnedit属性设置为repositoryitembuttonedit
把texteditstyle属性设置为hidetexteditor;
把buttons的kind属性设置为glyph;
把button的caption用于设置文字
把buttons的textoption的halignment属性设置为near;
如果要用到事件的话,还要注册事件。。。
在gridcontrol的设计器中repository页中的in-place editor repository项中
在右边的repository栏中找到你的buttonedit,选它的事件属性页,注册它的buttonclick事件即可
数据验证
有两种方法来实现基于单元格的验证:
1、使用repositoryitem.validating事件
事件的"sender" 必须转换为baseedit类型,使用editvalue来获取当前输入的值并进行校验,如果校验不通过,把e.cancel设置true。这种方法一般用来对内置控件的单元格进行数据验证。
private void textedit1_validating(object sender, system.componentmodel.canceleventargs e) { baseedit textedit = sender as baseedit; if (textedit.text.tostring().trim().length == 0) { e.cancel = true; //标识 错误提示 errorreason = 0; return; } else { //获取gridview中所有的选中的行号 //此处不允许多选,故只有一行 int[] irowid = this.gviewactlist.getselectedrows(); for (int i = 0; i < gviewactlist.datarowcount; i++) { //重复检验时,不验证当前行 if (i != irowid[0]) { if (textedit.editvalue.tostring().trim() == gviewactlist.getdatarow(i)["gridview上绑定的列名"].tostring().trim()) { e.cancel = true; //标识 错误提示 errorreason = 1; return; } } } } }
跟据validating事件中的标识,进行错误信息提示:
private void gviewactlist_invalidvalueexception(object sender, invalidvalueexceptioneventargs e) { if (errorreason == 0) { e.errortext = "动作名称不允许为空!"; } else if (errorreason == 1) { e.errortext = "动作名称不允许为重复!"; } else { e.errortext = "值无效!"; } }
2、使用 gridview.validatingeditor 事件
事件的"sender"必须转换为gridview类型,当前列可以从gridview.focusedcolumn属性获得,值可以从e.value获取,如果校验不通过,需要把e.valid设置为false。这种方法一般用于对整个grid内的文本框进行数据验证
private void gvlist_validatingeditor(object sender, devexpress.xtraeditors.controls.basecontainervalidateeditoreventargs e){ if (this.gvlist.focusedcolumn.fieldname == "passqty"){ string passqty = e.value.tostring().trim(); int receiveqty = orderdetaillist[this.gvlist.focusedrowhandle].qty; if (!jxtype.isintbigthanzero(passqty)){ e.valid = false; e.errortext = "合格数量必须为大于等于0, 并且小于等于接货数量的整数!"; }else{ if (int.parse(passqty) > receiveqty){ e.valid = false; e.errortext = "合格数量必须为大于0, 并且小于等于接货数量的整数!"; } } } }
在设置完事件之后需要写一个gridview.invalidvalueexception 的事件委托,如
private void gridview1_invalidvalueexception(object sender, devexpress.xtragrid.views.base.invalidvalueexceptioneventargs e) { e.throwexception = false; e.windowtext = "验证通过"; e.displayerror = true; }
3、使用 gridview.validaterow事件
在gridview的validaterow事件中加入数据校验代码:
#region 检查数据 private void gridview1_validaterow(object sender, validateroweventargs e){ gridview view = sender as gridview; view.clearcolumnerrors(); if (view.getrowcellvalue(e.rowhandle, "birthday") == dbnull.value){ e.valid = false; view.setcolumnerror(view.columns["birthday"], "必须指定出生日期"); } }
添加checkbox并支持多选操作.
optionsselection -> multiselect : true
multiselectmode : checkboxrowselect
全选和反选
这是一个比较难的问题,这里我结合网上寻找的资料总结了一个实体类贴上源代码
//------------------------------------------------------------------------------------- // all rights reserved , copyright (c) 2014 , zto , ltd . //------------------------------------------------------------------------------------- using system.drawing; using system.windows.forms; using devexpress.xtraeditors.repository; namespace zto.waybill.utilities { /// <summary> /// dev gridcontrol 创建全选复选框 /// /// 修改纪录 /// /// 2014-5-30 版本:1.0 yanghenglian 创建主键,注意命名空间的排序。 /// /// 版本:1.0 /// /// <author> /// <name>yanghenglian</name> /// <date>2014-5-30</date> /// </author> /// </summary> public class devcontrolhelper { /// <summary> /// 创建复选框 /// </summary> /// <param name="e"></param> /// <param name="chk"></param> public static void drawcheckbox(devexpress.xtragrid.views.grid.columnheadercustomdraweventargs e, bool chk) { repositoryitemcheckedit repositorycheck = e.column.columnedit as repositoryitemcheckedit; if (repositorycheck != null) { graphics g = e.graphics; rectangle r = e.bounds; devexpress.xtraeditors.viewinfo.checkeditviewinfo info; devexpress.xtraeditors.drawing.checkeditpainter painter; devexpress.xtraeditors.drawing.controlgraphicsinfoargs args; info = repositorycheck.createviewinfo() as devexpress.xtraeditors.viewinfo.checkeditviewinfo; painter = repositorycheck.createpainter() as devexpress.xtraeditors.drawing.checkeditpainter; info.editvalue = chk; info.bounds = r; info.calcviewinfo(g); args = new devexpress.xtraeditors.drawing.controlgraphicsinfoargs(info, new devexpress.utils.drawing.graphicscache(g), r); painter.draw(args); args.cache.dispose(); } } /// <summary> /// 全选,反选 /// </summary> /// <param name="gridview"></param> /// <param name="fieldname"></param> /// <param name="currentstatus"></param> /// <returns></returns> public static bool clickgridcheckbox(devexpress.xtragrid.views.grid.gridview gridview, string fieldname, bool currentstatus) { bool result = false; if (gridview != null) { gridview.clearsorting();//禁止排序 gridview.posteditor(); devexpress.xtragrid.views.grid.viewinfo.gridhitinfo info; point pt = gridview.gridcontrol.pointtoclient(control.mouseposition); info = gridview.calchitinfo(pt); if (info.incolumn && info.column != null && info.column.fieldname == fieldname) { for (int i = 0; i < gridview.rowcount; i++) { gridview.setrowcellvalue(i, fieldname, !currentstatus); } return true; } } return result; } } }
下面是使用步骤
窗体加载事件添加一些代码
private bool _mcheckstatus; //gridcontrol全选,作为全局变量,默认false private void frminputbill_load(object sender, eventargs e) { bandedgridview1.optionsbehavior.editable = false; bandedgridview1.optionsbehavior.readonly = true; var col = new bandedgridcolumn { fieldname = "check", visible = true, visibleindex = 0, columnedit = new repositoryitemcheckedit() }; col.optionscolumn.allowedit = true; //checkbox可以编辑改变 gridband1.columns.insert(0, col); bandedgridview1.click += bandedgridview1_click; bandedgridview1.customdrawcolumnheader += bandedgridview1_customdrawcolumnheader; bandedgridview1.datasourcechanged += bandedgridview1_datasourcechanged; //这里绑定数据源 } #region gridcontrol支持全选事件 private void bandedgridview1_click(object sender, eventargs e) { if (devcontrolhelper.clickgridcheckbox(this.bandedgridview1, "check", _mcheckstatus)) { _mcheckstatus = !_mcheckstatus; } } private void bandedgridview1_customdrawcolumnheader(object sender, columnheadercustomdraweventargs e) { if (e.column != null && e.column.fieldname == "check") { e.info.innerelements.clear(); e.painter.drawobject(e.info); devcontrolhelper.drawcheckbox(e, _mcheckstatus); e.handled = true; } } private void bandedgridview1_datasourcechanged(object sender, eventargs e) { gridcolumn column = this.bandedgridview1.columns.columnbyfieldname("check"); if (column != null) { column.width = 40; column.optionscolumn.showcaption = false; column.columnedit = new repositoryitemcheckedit(); } } #endregion
重绘单元格或者行的显示,使用customdrawcell()事件
通过在appearence中添加formatcondition,设置应用与整行,还是单一个单元格,使用customdrawcell事件。
void gridview1_customdrawcell(object sender, devexpress.xtragrid.views.base.rowcellcustomdraweventargs e) { var currentview = sender as gridview; if (currentview != null && e.rowhandle == currentview.focusedrowhandle) return; rectangle r = e.bounds; if (e.column.fieldname == "f_state") { if (e.cellvalue.tostring().equals("false")) { e.appearance.forecolor = color.red; e.appearance.drawstring(e.cache, e.displaytext, r); e.handled = true; } } }
数据导入导出
原文:export to xls and xlsx formats | winforms controls | devexpress documentation
xtragrid 支持html、xml、txt、xsl导出,对应的导出器是exporthtmlprovider、exportxmlprovider、 exporttxtprovider、exportxslprovider。都在命名空间devexpress.xtraexport里面。
这里封装了一个数据导出的方法,可以导出上述列举的类型,只需要传入相应类型的provider就可以了。
private void exportto(iexportprovider provider) { cursor currentcursor = cursor.current; cursor.current = cursors.waitcursor; this.findform().refresh(); baseexportlink link = gridview1.createexportlink(provider); (link as gridviewexportlink).expandall = false; link.exportto(true); provider.dispose(); cursor.current = currentcursor; }
调用时只需要创建一个相应的provider。
iexportprovider provider = new exportxlsprovider(fullfilename); //这里可以是exporthtmlprovider、exportxmlprovider、exporttxtprovider exportto(provider);
也可以
string path = "output.xlsx"; //customize export options (gridcontrol1.mainview as gridview).optionsprint.printheader = false; xlsxexportoptionsex advoptions = new xlsxexportoptionsex(); advoptions.allowgrouping = devexpress.utils.defaultboolean.false; advoptions.showtotalsummaries = devexpress.utils.defaultboolean.false; advoptions.sheetname = "exported from data grid"; gridcontrol1.exporttoxlsx(path, advoptions); // open the created xlsx file with the default application. process.start(path);
导入数据只尝试了导入excel的导入,利用odbc读取excel的数据到datatable中,再把datatable绑定到xtragrid中。这里也是封装了一个读取excel数据的方法。
private dataset getdatafromexcelwithappointsheetname(string path) { string strconn = "provider=microsoft.jet.oledb.4.0;" +"data source=" + path + ";" +"extended properties=excel 8.0;"; oledbconnection conn = new oledbconnection(strconn); conn.open(); //返回excel的架构,包括各个sheet表的名称,类型,创建时间和修改时间等 datatable dtsheetname = conn.getoledbschematable(oledbschemaguid.tables, new object[] { null, null, null, "table" }); //包含excel中表名的字符串数组 string[] strtablenames = new string[dtsheetname.rows.count]; for (int k = 0; k < dtsheetname.rows.count; k++) { strtablenames[k] = dtsheetname.rows[k]["table_name"].tostring(); } oledbdataadapter da = null; dataset ds = new dataset(); //从指定的表明查询数据,可先把所有表明列出来供用户选择 string strexcel = "select * from[" + strtablenames[0] + "]"; da = new oledbdataadapter(strexcel, conn); da.fill(ds); return ds; }
以这样方式调用。
dataset ds = getdatafromexcelwithappointsheetname(fullfilename);
导出到pdf
一种方法:
using devexpress.xtraprinting; // create a printingsystem component. devexpress.xtraprinting.printingsystem ps = new devexpress.xtraprinting.printingsystem(); // create a link that will print a control. devexpress.xtraprinting.printablecomponentlink link = new printablecomponentlink(ps); // specify the control to be printed. link.component = gridcontrol1; // generate a report. link.createdocument(); // export the report to a pdf file. string filepath = @"c:\gridcontrol.pdf"; link.printingsystem.exporttopdf(filepath); system.diagnostics.process process = new system.diagnostics.process(); process.startinfo.filename = filepath; process.start();
二种:
devexpress.xtragrid.views.grid.gridview view = gridcontrol1.mainview as devexpress.xtragrid.views.grid.gridview; if (view != null) { view.optionsprint.expandalldetails = true;//请注意,仅当gridoptionsprint.printdetails属性设置为true时,此设置才有效。 view.exporttopdf("mainviewdata.pdf"); }
行双击事件的处理
要响应gridview的单击或者双击事件,要设置gridview的optionsbehavior.editable=false。如果为true,它是不会响应这这两个事件的。 它本的的机制就是这样。
//双击行弹出rowdetail信息 private void gridview1_mousedown(object sender, mouseeventargs e) { devexpress.xtragrid.views.grid.viewinfo.gridhitinfo hinfo = gridview1.calchitinfo(new point(e.x,e.y)); if (gridview1.rowcount > 0 && e.button == mousebuttons.left && e.clicks == 2) { //判断光标是否在行范围内 if (hinfo.inrow) { //取得选定行信息 string nodename = gridview1.getrowcellvalue(gridview1.focusedrowhandle, "nodename").tostring(); //string nodename = gridview1.getrowcellvalue(gridview1.getselectedrows()[0], "nodename").tostring(); string sql = "select nodedetail from treelist where nodename = '" + nodename + "'"; sqlcommand comm = new sqlcommand(sql, conn); try { conn.open(); messagebox.show(comm.executescalar().tostring(), "detail"); } catch (exception ex) { messagebox.show(ex.message, "error"); } finally { conn.close(); } } } }
那么mousedown方法与doubleclick有什么区别呢?grid1_doubleclick(object sender, eventargs e)函数会捕获整个grid的双击事件而不仅仅是双击列表行事件,比如:你双击表头、列表展示数据的下方的空白部分都会引发grid1_doubleclick(object sender, eventargs e)函数,而viewhtlb_mousedown(object sender, mouseeventargs e)函数此时不会被激活。
定位到某数据/记录??
this.gridview.movefirst(); this.gridview.movenext(); this.gridview.movelast();
禁止 各列头 移动\排序\改变列宽
gridview1.optionscustomization.allowcolumnmoving = false; gridview1.optionscustomization.allowsort = false; gridview1.optionscustomization.allowcolumnresizing = false;
拖动滚动条时固定某一列
设置columns,选择要固定的列,设置fixed属性,
可以选择以下固定方式:
- a. 固定在左边、
- b. 固定在右边、
- c. 不固定。
呈现给用户自定义的菜单:
#region grid events private void gridview_popupmenushowing(object sender, devexpress.xtragrid.views.grid.popupmenushowingeventargs e) { if (e.menutype == devexpress.xtragrid.views.grid.gridmenutype.column) { devexpress.xtragrid.menu.gridviewcolumnmenu menu = e.menu as devexpress.xtragrid.menu.gridviewcolumnmenu; menu.items.clear(); if (menu.column != null) { menu.items.add(createcheckitem("取消固定", menu.column, devexpress.xtragrid.columns.fixedstyle.none, imagelist2.images[0])); menu.items.add(createcheckitem("固定到左边", menu.column, devexpress.xtragrid.columns.fixedstyle.left, imagelist2.images[1])); menu.items.add(createcheckitem("固定到右边", menu.column, devexpress.xtragrid.columns.fixedstyle.right, imagelist2.images[2])); } } } #endregion #region new column menu dxmenucheckitem createcheckitem(string caption, gridcolumn column, devexpress.xtragrid.columns.fixedstyle style, image image) { dxmenucheckitem item = new dxmenucheckitem(caption, column.fixed == style, image, new eventhandler(onfixedclick)); item.tag = new menuinfo(column, style); return item; } void onfixedclick(object sender, eventargs e) { dxmenuitem item = sender as dxmenuitem; menuinfo info = item.tag as menuinfo; if (info == null) return; info.column.fixed = info.style; } class menuinfo { public menuinfo(gridcolumn column, devexpress.xtragrid.columns.fixedstyle style) { this.column = column; this.style = style; } public devexpress.xtragrid.columns.fixedstyle style; public gridcolumn column; } #endregion
设置自动增加的行号
this.gridview1.indicatorwidth = 30;//设置显示行号的列宽
private void gridview_customdrawrowindicator(object sender,devexpress.xtragrid.views.grid.rowindicatorcustomdraweventargs e){ e.appearance.textoptions.halignment = devexpress.utils.horzalignment.far; if(e.info.isrowindicator){ if(e.rowhandle >= 0){ e.info.displaytext = (e.rowhandle + 1).tostring(); }else if(e.rowhandle > -1000 && e.rowhandle < 0){ e.info.appearance.backcolor = system.drawing.color.antiquewhite; e.info.displaytext = "g" + e.rowhandle.tostring(); } } }
在查询得到 0 条记录时, 显示自定义的字符提示
// when no records are being displayed private void gridview1_customdrawemptyforeground(object sender, customdraweventargs e) { // 方法一(此方法为gridview设置了数据源绑定时,可用) columnview columnview = sender as columnview; bindingsource bindingsource = this.gridview1.datasource as bindingsource; if(bindingsource.count == 0){ string str = "没有查询到你所想要的数据!"; font f = new font("宋体", 10, fontstyle.bold); var tmpleft = e.bounds.left + 5; var tmptop = e.bounds.top + 5; var tmpwidth = e.bounds.width - 5; var tmpheight = e.bounds.height - 5; rectangle r = new rectangle(tmpleft, tmptop, tmpwidth, tmpheight); e.graphics.drawstring(str, f, brushes.black, rect); } } // 方法二(此方法 适用于: gridview 没有设置数据源时) if (this._flag){ if (this.gridview1.rowcount == 0){ string str = "没有查询到你所想要的数据!"; font f = new font("宋体", 10, fontstyle.bold); var tmpleft = e.bounds.left + 5; var tmptop = e.bounds.top + 5; var tmpwidth = e.bounds.width - 5; var tmpheight = e.bounds.height - 5; rectangle r = new rectangle(tmpleft, tmptop, tmpwidth, tmpheight); e.graphics.drawstring(str, f, brushes.black, r); } }
到此这篇关于.net使用xtragrid控件绑定数据的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持代码网。
发表评论