设计数据源并绑定字段:
数据源可以是实现下列接口之一的任何类型:
- 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控件绑定数据的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持代码网。
发表评论