轉(zhuǎn)帖|使用教程|編輯:龔雪|2014-03-17 13:43:08.000|閱讀 2630 次
概述:雖然網(wǎng)上關(guān)于主從表(Master-Detail)如何動態(tài)加載明細(xì)表數(shù)據(jù)的文章很多了,但都不是很系統(tǒng),本文再進(jìn)行一下詳細(xì)的總結(jié)。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
主從表(Master-Detail)動態(tài)加載明細(xì)表效果如下圖:
實(shí)現(xiàn)過程說明如下:
1、程序開始時(shí)只加載主表的數(shù)據(jù),明細(xì)表內(nèi)容不加載;
2、如果選擇了新的主表對象,根據(jù)新主表對象ID,動態(tài)從數(shù)據(jù)庫中加載相關(guān)明細(xì)表的數(shù)據(jù),并合并到數(shù)據(jù)源的明細(xì)表中,同時(shí)把該主表的ID在List中緩存(以避免重復(fù)加載);
下面以nwind.mdb數(shù)據(jù)庫中的Orders和Order Details主從表為列說明具體過程。
做到一半發(fā)現(xiàn)MDB數(shù)據(jù)不支持DataSet一些特性,感覺很不爽,臨時(shí)更換為SQL數(shù)據(jù)庫,使用SQL 2005示例數(shù)據(jù)庫AdventureWorksDB,以Sales.SalesOrderHeader和Sales.SalesOrderDetail為例說明具體過程。
DevExpress DXperience教程教程環(huán)境必備:
1、SQL 2005示例數(shù)據(jù)庫AdventureWorksDB下載及安裝,可以下載并安裝;
2、IDE環(huán)境:VS.Net2008;
3、DXperience組件版本:9.2.6
代碼只用來說明問題,沒有詳細(xì)的錯(cuò)誤處理機(jī)制等。
1、運(yùn)行VS環(huán)境,并建立一個(gè)解決方案;
2、如果您沒有示例數(shù)據(jù)庫,可以到上面的下載地址去下載并安裝;
3、主窗體SmarTestMain中加入一個(gè)GridControl,并建立兩個(gè)視圖,名稱及關(guān)系如下圖所示:
4、向項(xiàng)目中添加一個(gè)DataSet數(shù)據(jù)集DSSalesOrder.xsd,添加一個(gè)到AdventureWorks數(shù)據(jù)庫的連接,如下圖所示:
5、把表SalesOrderHeader和SalesOrderDetail拖到DataSet設(shè)計(jì)器,自動建立關(guān)系,重新命名關(guān)系SOHeaderDetail,如下圖所示:
6、修改dataset中表SalesOrderDetail的查詢,在Fill,GetData()上點(diǎn)擊右鍵彈出菜單,選擇Configure,彈出配置窗體,在select語句后面加上查詢條件
where [email=SalesOrderID=@SalesOrderId]SalesOrderID=@SalesOrderId[/email]
下一 步;方法名稱修改為
FillBySalesOrderId/GetDataFillBySalesOrderId;
下一步結(jié)束。
7、設(shè)置gridControl1的數(shù)據(jù)源并設(shè)置其DataMember=SalesOrderHeader,在grindControl1的Level1上點(diǎn)擊,并選擇菜單Change LevelName,設(shè)置levelname=SOHeaderDetail,注意與數(shù)據(jù)集中定義的關(guān)系是一致的,如下圖所示:
8、運(yùn)行GridControlRunDesigner,選擇明細(xì)表視圖gvOrderDetails,點(diǎn)擊Columns/Retrieve Fields以自動生成明細(xì)視圖的列,將兩個(gè)gridViewOptionsView.ColumnAutoWidth=false。
9、接下來的任務(wù)是寫個(gè)簡單的數(shù)據(jù)訪問類,包括兩個(gè)方法,如下所示:
public static DSSalesOrder getSalesOrderAll() { DSSalesOrder dataSet = new DSSalesOrder(); using (SqlConnection con = new SqlConnection(Properties.Settings.Default.AdventureWorksConnectionString)) { using (DSSalesOrderTableAdapters.SalesOrderHeaderTableAdapter ta = new SmarTest.Template.DSSalesOrderTableAdapters.SalesOrderHeaderTableAdapter { Connection = con }) { ta.Fill(dataSet.SalesOrderHeader); } } return dataSet; } public static DSSalesOrder getSalesOrderDetailByOrderId(int salesOrderId) { DSSalesOrder dataSet = new DSSalesOrder(); using (SqlConnection con=new SqlConnection(Properties.Settings.Default.AdventureWorksConnectionString)) { using (DSSalesOrderTableAdapters.SalesOrderDetailTableAdapter ta = new SmarTest.Template.DSSalesOrderTableAdapters.SalesOrderDetailTableAdapter { Connection = con }) { ta.FillBySalesOrderId(dataSet.SalesOrderDetail, salesOrderId); } } return dataSet; }
關(guān)鍵是第二個(gè)方法,不是返回所有明細(xì)數(shù)據(jù),而是根據(jù)主表ID,返回相關(guān)的明細(xì)。
下面的步驟都很關(guān)鍵,一定要注意!
10、設(shè)置主表視圖 gvOrders屬性:
this.gvOrders.OptionsDetail.AllowExpandEmptyDetails = true;(此屬性在整個(gè)項(xiàng)目中起一個(gè)核心的作用,如果不設(shè)置此屬性,即使其它都正確,還是不會引發(fā)gvOrders_MasterRowGetChildList事件。)
this.gvOrders.OptionsDetail.AllowOnlyOneMasterRowExpanded = true;(可以不設(shè)置)
this.gvOrders.OptionsBehavior.Editable = false;(這里是因?yàn)槭褂昧薘owClick事件,二者有關(guān)系,所以設(shè)置)
12、gvOrders視圖必須響應(yīng)的事件
List<int> mSalesOrderCach = new List<int>(); int mSalesOrderId = -1; private void gvOrders_RowClick(object sender, DevExpress.XtraGrid.Views.Grid.RowClickEventArgs e) { var row = gvOrders.GetDataRow(e.RowHandle) as DSSalesOrder.SalesOrderHeaderRow; mSalesOrderId = row.SalesOrderID; gvOrders.ExpandMasterRow(e.RowHandle);//此語句非必須,主要是使新的主表焦點(diǎn)行立即展開明細(xì)表,即使不包括數(shù)據(jù)。否則需要點(diǎn)擊主表的焦點(diǎn)行的“+”展開。 } private void gvOrders_MasterRowGetChildList(object sender, DevExpress.XtraGrid.Views.Grid.MasterRowGetChildListEventArgs e) { if (mSalesOrderCach.Contains(mSalesOrderId)) return; using (DevExpress.Utils.WaitDialogForm wdf = new DevExpress.Utils.WaitDialogForm("向服務(wù)器請求數(shù)據(jù)...")) { var dsSalesOrder = gridControl1.DataSource as DSSalesOrder; using (DSSalesOrder ds=dbHelper.getSalesOrderDetailByOrderId(mSalesOrderId)) { if(ds.SalesOrderDetail.Rows.Count>0) { mSalesOrderCach.Add(mSalesOrderId); dsSalesOrder.SalesOrderDetail.Merge(ds.SalesOrderDetail); } } } }
怎樣才能不顯示子表的 ViewCaption?
設(shè)置主表視圖
gvOrders.gvOrders.OptionsDetail.ShowDetailTabs = false;
即可
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@ke049m.cn
文章轉(zhuǎn)載自:慧都控件網(wǎng)