DataTable,DataView和DataGrid中一些容易混淆的概念

一、DataTable
  
   DataTable表示內存中數據的一個表,它完全是在內存中的一個獨立存在,包含了這張表的全部信息。DataTable可以是從通過連接從數據庫中讀取出來形成的一個表,一旦將內容讀到DataTable中,此DataTable就可以跟數據源斷開而獨立存在;也可以是完全由程序自己通過代碼來建立的一個表。
  
  ◆ DataColumn
  
  一個表是由行和列組成的一個兩維的結構。表的結構是由DataColumn 對象的集合組成,DataColumn 對象集合可由DataTable.Columns 屬性中能獲取到,通過定義每一列的數據類型來確定表的架構,類似數據庫中定義表。定義完表的結構就可以根據結構來生成DataRow,用 DataTable.NewRow()方法來生成此DataTable結構的新行。
  一個DataTable是由DataRow的集合組成的, DataRow的集合這個可以由DataTable.Rows 屬性來訪問。
  
  DataTable還可以通過現有的列用Expression 屬性的表達式創建一些列。
  
  1、創建計算出的列
  比如:已經有了一個表結構,表中有一個DataColumn的集合,其中有一個叫UnitPrice的列,你可以新建一個DataColumn,設置好ColumnName,再設置此列的表達式,DataColumn.Expression = "UnitPrice * 0.086",這個列的值就是名字爲UnitPrice的列計算出來的,在創建表達式時,使用 ColumnName 屬性來引用列。
  
  2、第二個用途是創建聚合列
  聚合列聚合通常沿着關係執行(有關關係的描述見下面DataRelation部分),如果order表有名爲 detail 的子表,兩個表之間通過order.orderid和detail.orderid兩個列建立一個關係 DataRelation 對象名爲“order2detail”,在主表order中就可以建立一個聚合列,將計算每個order在detail表中含有的所有item的價格的和:DataColumn.Expression = “sum(child(order2detail).price)",child(order2detail)表示通過關係order2detail聯繫到的子表,child(order2detail).price就表示子表的price列。
  
  ◆ DataRow
  
  DataRow對象沒有直接在代碼中使用的構造函數,一般是從具有一定結構的DataTable用NewRow()方法來新建一個DataRow對象。一個DataRow根據其是獨立的,還是屬於某個DataTable,是否修改過,是否被DataTable刪除等等不同的情況有不同的狀態,由 DataRow.RowState屬性公開,如下表:
  成員名稱
  
  說明
  Added 該行已添加到 DataRowCollection 中,AcceptChanges 尚未調用。Deleted 該行已通過 DataRow 的 Delete 方法被刪除。
  Deleted 該行已通過 DataRow 的 Delete 方法被刪除。
  Detached 該行已被創建,但不屬於任何 DataRowCollection。DataRow 在以下情況下立即處於此狀態:創建之後添加到集合中之前;或從集合中移除之後。
  Modified 該行已被修改,AcceptChanges 尚未調用。
  Unchanged 該行自上次調用 AcceptChanges 以來尚未更改。
  
  一個DataRow對象剛被創建之後其狀態是Detached,是孤立的一個存在,所以建立了DataRow之後在DataRow中的單元填充了數據後還要通過DataTable.Rows.Add(DataRow)方法將此DataRow添加到DataTable,DataRow添加到 DataTable後, 這個DataRow的狀態就轉變爲Added。當修改了這個DataRow後,這個DataRow狀態轉爲Modified,當用 DataRow.Delete()方法刪除DataRow後,DataRow狀態將轉爲Deleted,不過此行還存在在DataTable中的,只是狀態改變了,這時用DataTable.Rows.Count查看行數,跟刪除前是一樣的。只有在調用了DataTable.Remove (DataRow)方法後,此DataRow才被從DataTable移除,狀態也回覆到Detached孤立狀態。
  
  一旦調用了DataTable.AcceptChanges()方法後,所有的行將根據不同的狀態做不同的處理,Added、Modified、 Unchanged將保留當前值,Deleted的行將從DataTable中移除,最後所有的行的狀態都置爲Unchanged。當DataTable 是從DataAdapter.Fill(DataSet,DataTable)方法填充而形成的,Fill()方法將自動調用AcceptChanges ()方法,將DataTable的行狀態都置爲Unchanged。並且,如果Fill方法中指定的那個DataTable在要填充的那個DataSet 不存在時,會生成一個跟數據源表同樣的結構的DataTable並填充數據。
  
  ◆ DataRelation
  
  表示兩個 DataTable 對象之間的父/子關係。可以類比於數據庫中的表之間的關係,父表相當於關係列爲主鍵的表,子表相當於關係列爲外鍵的表。DataRelation 構造函數一般爲:DataRelation(String, DataColumn, DataColumn) ,string爲關係名,第一個DataColumn爲建立關係的父表列,第二個DataColumn爲建立關係的子表列,建立關係的兩個列的 DataType 值必須相同。
  
  建立好了關係,必須把這個關係加入到DataTable的ParentRelations屬性或ChildRelations 屬性,這兩個屬性包含這個表的所有的跟父表的關係和跟子表的關係。若關係中此表是父表則將此關係加入到ChildRelations集合中,否則加入到 ParentRelations集合中。
  
  二、DataView
  
  DataView表示用於排序、篩選、搜索、編輯和導航的 DataTable 的可綁定數據的自定義視圖。可以將DataView同數據庫的視圖類比,不過有點不同,數據庫的視圖可以跨表建立視圖,DataView則只能對某一個 DataTable建立視圖。DataView一般通過DataTable.DefaultView 屬性來建立,再通過通過RowFilter 屬性和RowStateFilter 屬性建立這個DataTable的一個子集。
  
  RowFilter屬性用來篩選要查看DataTable中哪些行的表達式,這個表達式同上面所說的建立計算列的表達式相同。例如:"LastName = 'Smith'",這就是隻查看列LastName的值爲'Smith'的那些數據行。
  
  RowStateFilter 屬性用來設置 DataView 中的行狀態篩選器,上面介紹DataRow時介紹了DataRow的狀態,一個DataRow可能有五種狀態,RowStateFilter就是可以通過這些狀態來篩選要查看的行集。其實DataRow不僅有五種狀態,DataRow還有版本的問題,比如當DataRow的狀態爲Modified,即這行已經被修改了,這時這個DataRow就會有兩個版本,Current版本和Original版本(修改前的)。實際上RowStateFilter屬性是綜合了DataRow的狀態和版本來篩選的(RowStateFilter確省值是CurrentRows)見下表:
  成員名稱
  
  說明
  Added 一個新行。
  CurrentRows 包括未更改行、新行和已修改行的當前行。
  Deleted 已刪除的行。
  ModifiedCurrent 當前版本,原始數據(請參閱 ModifiedOriginal)的修改版本。
  ModifiedOriginal 原始版本(儘管它後來已被修改並以 ModifiedCurrent 形式存在)。
  None 無。
  OriginalRows 包括未更改行和已刪除行的原始行。
  Unchanged 未更改的行。
  
  DataView.Count屬性得到的計數是在應用了 RowFilter 和 RowStateFilter 之後,獲取 DataView 中記錄的數量。
  
  DataView是建立在DataTable基礎上的,DataView.Table 屬性可以得到此DataView對應的那個DataTable。DataView的行叫DataRowView,可以從DataRowView直接通過 DataRowView.Row 屬性得到此DataRowView對應的DataRow。
  
  三、DataGrid
  
  這裏說的DataGrid是winform中的DataGrid,一般都是跟DataView綁定來顯示DataTable中的數據,和修改DataTable中的數據。
  DotNet的DataGrid的功能強大,可是在使用上與以前的習慣不太一樣,有時還比較麻煩,所以很多人都對這個DataGrid感到有些摸不着頭腦,有一種無從下手的感覺,其實把一些概念搞清楚了許多問題就會迎刃而解了。
  
  DataGrid通過DataSource 和 DataMember 屬性來綁定其要顯示的數據源。數據源一般是DataTable、DataView、DataSet等,不過將這些數據源綁定到DataGrid時實際上是綁定的DataView。若數據源是DataTable時,實際上是綁定了此DataTable的DefaultView,若數據源是DataSet時,則可以向 DataMember 屬性設置一個字符串,該字符串指定要綁定到的表,然後再將DataMember指定的那個DataTable的DefaultView綁定到 DataGrid。
  
  所以DataGrid實際顯示的是DataTable經過篩選的DataView。
  
  ◆ DataGrid以何種方式顯示DataView的數據
  
  DataGrid綁定到一個DataView後,由DataGrid.TableStyles中的DataGridTableStyle 對象的集合來控制這個DataView的哪些列要顯示,列的寬度多少,列標頭的文本是什麼等等。確省的DataGrid.TableStyles中不包含任何對象,這時DataGrid將會按照DataView列的順序將所有的列都顯示出來。一般應用中都會設置TableStyles來控制顯示的內容及格式。
  
  例如DataGrid綁定到一張叫order的DataTable,這個DataTable包含了OrderID、CustomerID、 OrderDate、ShipName、ShipAddress等字段,如果不用TableStyles來控制顯示的列和格式,將得到以下的顯示結果:
  
  figure-1
  
  可以看到DataGrid將會按照DataView列的順序將所有的列都顯示出來
  
  我們只想顯示OrderID、CustomerID、OrderDate這三個字段,並且想將OrderID的列表頭顯示爲“訂單號”,CustomerID顯示爲“客戶號”,OrderDate顯示爲“訂單日期”,這就要用TableStyles來控制了。
  新建一個TableStyle,將此TableStyle.MappingName屬性對應到這個TableStyle要控制的那個DataTable的名字:
   DataGridTableStyle myTableStyle = new DataGridTableStyle();
  myTableStyle.MappingName = "myDateTable";
  
  再建立三個DataGridColumnStyle,分別用來控制將要顯示的三個列:
  
  
  DataGridColumnStyle myColumnStyle1 = new DataGridTextBoxColumn();
  myColumnStyle1.MappingName = "OrderID";
  myColumnStyle1.HeaderText = "訂單號";
  
  DataGridColumnStyle myColumnStyle2 = new DataGridTextBoxColumn();
  myColumnStyle2.MappingName = "CustomerID";
  myColumnStyle2.HeaderText = "客戶號";
  
  DataGridColumnStyle myColumnStyle3 = new DataGridTextBoxColumn();
  myColumnStyle3.MappingName = "OrderDate";
  myColumnStyle3.HeaderText = "訂單日期";
  
  將這三個DataGridColumnStyle添加到TableStyle中:
  
  
  myTableStyle.GridColumnStyles.Add(myColumnStyle1);
  myTableStyle.GridColumnStyles.Add(myColumnStyle2);
  myTableStyle.GridColumnStyles.Add(myColumnStyle3);
  
  最後將TableStyle添加到DataGrid中:
  
  
  dataGrid1.TableStyles.Add(myTableStyle);
  
  將 TableStyle添加到DataGrid後,再綁定數據源,這時我們就會看到這樣的數據顯示了:
  
  figure-2
  
  ◆ DataGrid的編輯修改
  
  DataGrid支持對DataGrid所顯示的DataTable的編輯修改,只要DataGrid的ReadOnly屬性爲False,就可以在DataGrid中直接修改單元中的內容,修改完後數據將直接反應到此DataGrid對應的那個DataTable的單元。
  
  如果這個DataTable是通過vs.net的可視化數據設計器新建DataAdapter,並生成了SelectCommand、 InsertCommand、UpdateCommand、DeleteCommand這四個命令,用DataAdapter的Fill方法得來的,那麼事情就簡單了,修改過的DataTable你可以直接用DataAdapter的UpDate方法寫回到數據庫。下面看一下vs.net的可視數據數據器生成的InsertCommand命令:
  
  this.sqlInsertCommand1.CommandText = @"INSERT INTO Customers(CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax) VALUES (@CustomerID, @CompanyName, @ContactName, @ContactTitle, @Address, @City, @Region, @PostalCode, @Country, @Phone, @Fax); SELECT CustomerID, CompanyName, ContactName, ContactTitle, Address, City, Region, PostalCode, Country, Phone, Fax FROM Customers WHERE (CustomerID = @CustomerID)";
  this.sqlInsertCommand1.Connection = this.sqlConnection2;
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CustomerID", System.Data.SqlDbType.NVarChar, 5, "CustomerID"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@CompanyName", System.Data.SqlDbType.NVarChar, 40, "CompanyName"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@ContactName", System.Data.SqlDbType.NVarChar, 30, "ContactName"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@ContactTitle", System.Data.SqlDbType.NVarChar, 30, "ContactTitle"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Address", System.Data.SqlDbType.NVarChar, 60, "Address"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@City", System.Data.SqlDbType.NVarChar, 15, "City"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Region", System.Data.SqlDbType.NVarChar, 15, "Region"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@PostalCode", System.Data.SqlDbType.NVarChar, 10, "PostalCode"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Country", System.Data.SqlDbType.NVarChar, 15, "Country"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Phone", System.Data.SqlDbType.NVarChar, 24, "Phone"));
  this.sqlInsertCommand1.Parameters.Add(new System.Data.SqlClient.SqlParameter("@Fax", System.Data.SqlDbType.NVarChar, 24, "Fax"));
  
  DataAdapter的SelectCommand是用來DataAdapter.Fill()方法來填充DataTable的,SelectCommand選擇的數據錶行集將被填充到DataTable中,然後DataGrid將它顯示出來。
  
  DataGrid在經過編輯修改後,其對應的DataTable中的行就可能出現文章上面所述的那五種狀態,可能是新加的(Added),可能是修改了的(Modified),可能是刪除的(Deleted),DataAdapter.UpDate()方法將通過調用InsertCommand命令將狀態爲Added的行插入到數據庫,UpdateCommand將狀態爲Modified的行在數據庫中做修改,DeleteCommand將狀態爲 Deleted的行在數據庫真正的刪除。
  
  如果不是通過vs.net的可視化數據設計器新建DataAdapter,沒有自動生成SelectCommand、InsertCommand、 UpdateCommand、DeleteCommand這四個命令,那麼就可能需要自己寫InsertCommand、UpdateCommand、 DeleteCommand命令,有一種情況就是當SelectCommand至少返回一個主鍵列或唯一的列時,可以通過 SqlCommandBuilder來自動根據SelectCommand命令來自動生成另外三個更新命令,例如:
  
  SqlConnection myConn = new SqlConnection(myConnection);
  SqlDataAdapter myDataAdapter = new SqlDataAdapter();
  myDataAdapter.SelectCommand = new SqlCommand(mySelectQuery, myConn); //建立DataAdapter的SelectCommand命令
  SqlCommandBuilder custCB = new SqlCommandBuilder(myDataAdapter);//建立此DataAdapter的CommandBuilder,
   //這樣系統就會給此DataAdapter自動生成InsertCommand、UpdateCommand、DeleteCommand三個命令。
  
  否則,要用DataAdapter.UpDate()方法更新數據庫就要自己寫InsertCommand、UpdateCommand、DeleteCommand這三個命令,可以參考上面給出的vs.net自動生成的InsertCommand命令的寫法。
  
  ◆ 數據綁定的同步
  
  WinForm中很多控件都可以與數據源綁定,綁定又分兩種情況:
  
  簡單數據綁定
  簡單數據綁定指將一個控件綁定到單個數據元素(如數據集表的列中的值)的能力。這是用於控件,如 TextBox 控件或 Label 控件(即通常只顯示單個值的控件)的典型綁定類型。事實上,控件上的任何屬性都可以綁定到數據庫中的字段。
  
  複雜數據綁定
  複雜數據綁定指將一個控件綁定到多個數據元素的能力,通常綁定到數據庫中的多條記錄,或者綁定到多個任何其他類型的可綁定數據元素,一般是綁定到一個DataView。支持複雜綁定的控件的示例有DataGrid、ListBox 和 ErrorProvider 控件。
  
  一般DataGrid控件都是跟一個DataView綁定,DataGrid的數據綁定屬於複雜綁定,因爲它綁定到有多條記錄的表,DataGrid有兩個屬性同數據綁定有關:
  
  DataGrid.DataSource 屬性:獲取或設置DataGrid所顯示數據的數據源。一般是跟DataTable 、DataView 、DataSet 綁定,如果DataSource設定爲DataSet,則引用包含的表不止一個,則必須向 DataMember 屬性設置一個字符串,該字符串指定要綁定到的表。
  
  DataGrid.DataMember 屬性:獲取或設置 DataSource中的特定列表,就是上述DataSource設定爲DataSet時,要設定此屬性來指定要綁定到的表。
  
  經常有這種需求,一個窗體中有一個DataGrid,顯示了一些數據,窗體上還有一些TextBox控件,用來顯示DataGrid中的當前行的數據,一個TextBox控件對應DataGrid行的一個列,當DataGrid的當前行移動時,TextBox控件中的值也會跟着顯示改變後的 DataGrid的當前行。
  
  要保證這些數據綁定控件保持同步就要一個統一管理數據綁定的機制來保證這些控件的同步,DotNet中負責數據同步的是 BindingManagerBase,它是用來管理數據源的,綁定到同一個數據源的數據綁定控件都可以由BindingManagerBase統一管理。BindingManagerBase可以由Form.BindingContext.Item屬性獲得,此屬性有兩種重載:
  
  public BindingManagerBase this[object DataSource] //獲取與指定數據源關聯的 BindingManagerBase
  public BindingManagerBase this[object DataSource, string DataMember] //獲取與指定數據源和數據成員相關聯的一個 BindingManagerBase
  
  所有的數據綁定控件的數據源同建立BindingManagerBase時傳遞的對象一樣的,都將屬於這個BindingManagerBase管理,比如,建立一個如下的BindingManagerBase:
  
  BindingManagerBase myBindingManagerBaseParent = this.BindingContext[myDataSet,"customers"];
  
  如果Form上有個DataGrid的DataGrid.DataSource = myDataSet;DataGrid.DataMember = "customers",那麼這個DataGrid的數據源就在myBindingManagerBaseParent的管理之下了。
  同樣簡單數據綁定的控件的DataSource也是跟 BindingManagerBase的DataSource一樣,DataMember是BindingManagerBase的DataMember 指定的那個表的某一列時,這個控件的數據源也在這個myBindingManagerBaseParent管理之下了:
  
  dataGrid1.DataSource = myDataSet;
  dataGrid1.DataMember = "customers";
  textCustomerId.DataBindings.Add(new Binding("Text",myDataSet,"customers.customerid")); //TextBox的Text屬性跟
   //myDataSet的customers表的customerid字段綁定
  
  BindingManagerBase控制的數據源有個當前行的概念,控件一旦跟數據源綁定後,DataGrid將顯示數據源表的所有數據,不過在DataGrid的行標頭裏有個黑色的三角箭頭用來指示當前行。簡單綁定控件中顯示的值將是數據源當前行的內容。
  
  所以,只要我們改變BindingManagerBase的指針就行了,這個可以在界面上通過點擊要到的那一行來改變當前行,也可以在程序中改變當前行的設置:
  
  myBindingManagerBaseParent.Position = 10;
  
  BindingManagerBase.Position屬性的變化就會引起BindingManagerBase當前行的變化,也就是跟這個數據源綁定的DataGrid的當前行的變化,簡單綁定控件的顯示內容也就隨之改變了,如下圖。
  
  figure-3
  當前行是第一行,上面的三個
  TextBox控件也顯示第一行的數據
  
  
  figure-4
  當前行是第四行,上面的三個
  TextBox控件也顯示第四行的數據
  
  BindingManagerBase的DataSource可以是DataSet,DataSet中可以有多個DataTable,這些 DataTable可以通過DataRelaton(關係)聯繫在一起,形成父表/子表的關係。比如,還是上面舉過的例子,一個DataGrid顯示 Customer表,同時還想要有一個DataGrid來顯示當前Customer所有的order。這樣我們就會需要兩個 BindingManagerBase了,一個BindingManagerBase對應Customer表,另一個 BindingManagerBase對應order表,而且這個order表還要考慮到同Customer表的關係。
  
  對應Customer的BindingManagerBase上面我們已經建立好了,下面我們來建立對應order的BindingManagerBase:
  
  首先我們要建立Customer表和order表之間的關係myRelation:
  
  DataColumn ParentColumn = myDataSet.Tables["customers"].Columns["customerid"]; //要建立關係的父表的列,相當於主鍵
  DataColumn ChildColumn = myDataSet.Tables["orders"].Columns["customerid"]; //要建立關係的子表的列,相當於外鍵
  DataRelation myRelation = new DataRelation("myRelation",ParentColumn,ChildColumn,false); //根據父表,子表的相關列建立關係
  
  然後,通過關係,建立對應order表的BindingManagerBase:
  
  myBindingManagerBaseChild = this.BindingContext[myDataSet,"customers.myRelation"]; //這個數據源將解析爲一個父表中的客戶對應的所有的order
  
  這樣,當對應Customer的BindingManagerBase的當前行改變時,對應order的BindingManagerBase也將跟着變化,他們之間的關係是由myRelation決定的,如下圖:
  
  
  figure-5
  對應子表order的DataGrid顯示對應父表中ALFKI 客戶的所有order,當點擊了“主表下移一行”按鈕時,父表中的當前客戶改變爲ANATR時, 子表同樣也改變爲顯示對應ANATR的所有order了
  
  ◆ 在程序中訪問DataGrid中的內容
  
  DataTable中有數據行DataRow,而在DataGrid中沒有行這個對象,這讓人感到很不習慣,也覺得不夠自然。在DataTable 中,一張表的層次結構很清楚,DataTable.Rows屬性可以得到這張表所包含的所有行的行集,通過行集的索引DataRowCollection [index]就可以得到具體的一個DataRow,數據行的索引DataRow[index]又可以得到這一行的具體某一列的內容。
  而DataGrid 中就沒有這麼方便了,DataGrid只有兩個屬性可用,DataGrid.CurrentCell 屬性,此屬性返回一個DataGridCell類型的結構,DataGridCell結構指明此Cell所在的行號和列號。還有一個 DataGrid.Item 屬性,此屬性有兩個重載:
  
  
  public object this[DataGridCell] //獲取或設置指定的 DataGridCell 的值
  public object this[int, int] //獲取或設置位於指定行和列的單元格的值
  
  可見,DataGrid中訪問都是針對某個Cell進行的。經常的,我們需要從當前的Cell獲得此Cell所對應的DataRow,比如界面中可能先選中DataGrid的某一行,或者某一個Cell,然後點擊一個按鈕,彈出一個新的窗口,窗口中顯示這一行的所有單元的內容,並允許修改單元的值,最後保存關閉窗口。這就需要從當前的DataGrid所在的單元找到其所對應的DataTable所在的行和列。
  
  而DataGrid中顯示的數據可能經過DataView的DataView.RowFilter屬性、 DataView.RowStateFilter屬性的過濾,還可能經過DataGrid本身根據各個列的正向和反向排序,所以DataGrid的 CurrentRowIndex屬性所指示的行索引跟其對應的DataTable的行索引有很大的機會是不一樣的,不能夠根據DataGrid的 CurrentRowIndex去獲取其對應的DataTable的行。
  
  這時BindingManagerBase又將發揮作用了,我們可以先建立一個對應此DataGrid綁定的數據源的BindingManagerBase,這樣這個BindingManagerBase就可以管理這個數據源。
   //設置DataGrid的數據源
  dataGrid1.DataSource = myDataSet;
  dataGrid1.DataMember = "customers";
  //建立同DataGrid同樣數據源的BindingManagerBase
  BindingManagerBase myBindingManagerBaseParent = this.BindingContext[myDataSet,"customers"];
  
  一旦建立了這個BindingManagerBase,就可以通過BindingManagerBase的當前行的屬性來獲取當前數據源的記錄:
   //BindingManagerBase的Current返回數據源的對象,對於綁定到DataView的數據源,需要將此對象顯式
  //的轉換爲 DataRowView類型
  DataRowView myDataRowView =(DataRowView) myBindingManagerBaseParent.Current
  
  這樣,我們就可以從當前的Cell得到此Cell所在的DataRowView,DataRowView又可以通過DataRowView.Row屬性及其方便的得到DataRow。
  
  如果還要進一步,想要得到此Cell所對應的DataTable的具體單元,就是不光要得到DataRow,還要知道這個Cell所對應的列。
  
  這又分兩種情況:
  
  一是DataGrid未使用TableStyles來設置DataGrid要顯示的列和格式,數據源DataView的所有列都將按照DataView本身的順序顯示出來,這樣可以直接取得對應的列索引:
   //獲取當前DataGrid單元的列索引,這個索引跟DataTable的索引是一樣的
  Int ColumnNumber = DataGrid.CurrentCell.ColumnNumber;
  
  另一種情況是DataGrid使用了TableStyles來設置DataGrid要顯示的列和格式,這樣DataGrid單元的列索引跟DataTable的索引就可能是不一樣的了,這就要用DataGrid的TableStyles了:
   Int ColumnNumberDataGrid = DataGrid.CurrentCell.ColumnNumber; //獲取當前DataGrid單元的列索引
  Int ColumnNumberDataTable = DataGrid.TableStyles[0].GridColumnStyles[ColumnNumberDataGrid].MappingName 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=1621438

 
發佈了2 篇原創文章 · 獲贊 1 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章