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

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  方法被删除。 该行已被创建,但不属于任何 DataRowCollection。DataRow  在以下情况下立即处于此状态:创建之后添加到集合中之前;或从 Detached 集合中移除之后。

 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 来控制显示的列和格式我们只想显示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 后,再绑定数据源,这时我们就会看到这样的数据显示了:

 

◆ 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 的当前行

 的变化,简单绑定控件的显示内容也就随之改变了, 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"]; //这个数据源将解析为一个父表中的客户对应的所有

这样,当对应Customer 的BindingManagerBase 的当前行改变时,对应order 的BindingManagerBase 也将跟着变化,他们之间的关系

 是由myRelation 决定的,对应子表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

 翟阿靖

 

你可能感兴趣的:(Datatable)