datagrid使用技巧(四)
------------如何在datagrid中显示来自不同datatable的数据
有时候听有些朋友抱怨.net的datagrid不是很好用。就我个人的体会,datagrid的功能非常强大,可以使我们随心所欲的完成各种各样的工作,可惜就是实现起来不够简单明了。我对平时经常碰到的一些问题积累了一些解决的方法,现在把它们总结一下供大家参考。
比较经常碰到的一个问题是:如何将来自不同datatable的字段组合显示在datagrid中?当然,可以将数据合并到一个datatable中,但有时候由于其他限制不能将数据合并,下面提供了一种在datagrid中显示来自不同datatable(同在一个dataset中)的数据的方法。
数据在dataset中的结构
我们希望数据在datagrid中如下图显示
下面用一个例子说明如何实现将来自不同datatable的数据显示在datagrid中。
基本思路:很显然,datagrid不能同时绑定两个datatable,那么,要使它显示两个不同datatable的数据,就只有在datagridcolumn中下功夫了。以上面的结构为例,我们建立一个继承datagridtextboxcolumn的类datagridjoincolumn,重载getcolumnvalueatrow方法。这个类要实现的功能是:数据源是datatable1,返回值是datatable1.employeeid对应的datatable2.lastname或datatable2.firstname。datatable1.employeeid与datatable2.employeeid是1对多联系,我们将这个联系添加到dataset中,就可以通过getparentrow(relation)方法取得datatable1.employeeid对应的datatable2.lastname和datatable2.firstname的值。具体代码如下:
public class jointextboxcolumn : datagridtextboxcolumn
{
string relation; //表示datatable1.employeeid与datatable2.employeeid的1对多联系
datacolumn col; //表示返回datatable2的列
public jointextboxcolumn(string relation,datacolumn col )
{
this.relation=relation;
this.col=col;
base.readonly=true;
}
protected override object getcolumnvalueatrow(currencymanager cm,int rownum)
{
try
{
datarow dr=((dataview)cm.list)[rownum].row;
datarow parentdr=dr.getparentrow(relation);
return parentdr[col]; //返回值是datatable1.employeeid对应的lastname或firstname
}
catch
{
return ""; //避免在添加新行时发生异常
}
}
protected override bool commit(currencymanager cm,int rownum)
{
return false;
}
public new bool readonly
{
get {return true;}
}
}
下面的代码说明了如何使用类datagridjoincolumn。新建一个windows程序,加入一个datagrid和一个sqlconnection,连接数据库northwind。 在form_load中加入下面代码:
private void form1_load(object sender, system.eventargs e)
{
sqldataadapter sda1=new sqldataadapter("select employeeid,lastname,firstname from employees",this.sqlconn);
sqldataadapter sda3=new sqldataadapter("select orderid,employeeid,orderdate,requireddate from orders",this.sqlconn);
ds=new dataset();
sda1.fill(ds,"emp");
sda3.fill(ds,"ord");
ds.relations.add("ord_emp",ds.tables["emp"].columns["employeeid"],ds.tables["ord"].columns["employeeid"]);
ds.tables["ord"].columns.add("lastname",typeof(string));
ds.tables["ord"].columns.add("firstname",typeof(string));
datagridtablestyle dt=new datagridtablestyle();
datagridcolumnstyle dc;
dc=new datagridtextboxcolumn();
dc.mappingname="orderid";
dc.headertext="orderid";
dt.gridcolumnstyles.add(dc);
dc=new datagridtextboxcolumn();
dc.mappingname="employeeid";
dc.headertext="employeeid";
dt.gridcolumnstyles.add(dc);
dc=new jointextboxcolumn("ord_emp",ds.tables["emp"].columns["firstname"]);
dc.mappingname="firstname";
dc.headertext="firstname";
dt.gridcolumnstyles.add(dc);
dc=new jointextboxcolumn("ord_emp",ds.tables["emp"].columns["lastname"]);
dc.mappingname="lastname";
dc.headertext="lastname";
dt.gridcolumnstyles.add(dc);
dc=new datagridtextboxcolumn();
dc.mappingname="orderdate";
dc.headertext="orderdate";
dt.gridcolumnstyles.add(dc);
dc=new datagridtextboxcolumn();
dc.mappingname="requireddate";
dc.headertext="requireddate";
dt.gridcolumnstyles.add(dc);
dt.mappingname="ord";
this.datagrid1.tablestyles.add(dt);
this.datagrid1.datasource=ds;
this.datagrid1.datamember="ord";
}