本文档说明如何使用由数据源提供的方法,为 DataTable 实现主/从关系。
ADO .NET 允许在数据表之间实现主/从关系。 ADO .NET 中的关键对象是 DataTable,它封装了内存中数据的二维表。 通过父表的 DataTable.ChildRelations 属性,可以定义在两个表间的主/从关系。 如果把网格控件绑定到包含了主/从关系的 DataTable,或者绑定到引用该表的 DataView,则网格可以获取此关系,仅需要您做的是为 XtraGrid 中表示的特定关系指派 模式视图。要获得关于其他主/从模式实现的信息,请参阅 主/从模式概述 文档。
步骤
绑定数据 文档提供了关于把 XtraGrid 绑定到数据源的总说明。 如果数据源包含主/从关系,则网格控件必须被绑定到主表。
主表被显示在 XtraGrid 的 GridControl.MainView 中。 展开主控行,则打开细节视图 (克隆),每个细节视图都显示与当前主控行关联的细节数据。 要为这些细节视图指定布局和外观设置,则需要把 模式视图 指派到主/从关系。 模式视图将用作创建主控行的细节 (克隆) 视图的模板。 要获得更多关于模式视图与克隆视图的信息,请参阅 模式视图与克隆视图 文档。
在本示例中,从 NWind 数据库的 Categories 和 Products 表中获取数据,并在 XtraGrid 中使用 网格视图 和 卡片视图 呈现这些表。 NWind 数据库与 XtraGrid 一起提供。对于 Categories 和 Products 表,主/从关系是通过 CategoryID 字段确立的 (Categories 是主表,Products 是从表)。
下面的小节展示了如何实现主/从关系,并在设计时刻和通过代码在 XtraGrid 中呈现。 给定代码与设计时刻的操作不完全等价。 只是为了简要说明所列出的主要步骤。- 从数据库中取出数据 (译者注: 如果您使用的是 VS2005 以上版本,则在设计时刻添加数据源的操作与本文中介绍的不同,请参阅其他资料,例如 如何: 在 VS2005 中的设计时刻绑定控件到数据库。)
- 创建和装载主表、从表
- 设置主/从关系
- 把 XtraGrid 绑定到主表
- 指定和定制呈现表的视图
1. 从数据库中取出数据
我们需要分别从数据库的 Categories 和 Products 表中获取数据。 因此,必须创建两个 OleDbDataAdapter 对象。 下列代码演示了如何执行此任务:
C# | 复制代码 |
---|---|
//Define a connection to the database OleDbConnection connection = new OleDbConnection( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\\Data\\nwind.mdb"); //Create data adapters for retrieving data from the tables OleDbDataAdapter AdapterCategories = new OleDbDataAdapter( "SELECT CategoryID, CategoryName, Picture FROM Categories", connection); OleDbDataAdapter AdapterProducts = new OleDbDataAdapter( "SELECT CategoryID, ProductID, ProductName, UnitPrice FROM Products", connection); |
Visual Basic | 复制代码 |
---|---|
'Define a connection to the database Dim connection As OleDbConnection = New OleDbConnection( _ "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\Data\nwind.mdb") 'Create data adapters for retrieving data from the tables Dim AdapterCategories As OleDbDataAdapter = New OleDbDataAdapter( _ "SELECT CategoryID, CategoryName, Picture FROM Categories", connection) Dim AdapterProducts As OleDbDataAdapter = New OleDbDataAdapter( _ "SELECT CategoryID, ProductID, ProductName, UnitPrice FROM Products", connection) |
2. 创建和装载主数据表、从数据表
在设计时刻创建一个 DataSet,使用鼠标右键单击这两个适配器组件中的一个,并从上下文菜单中选中 Generate Dataset(生成数据集)... 选项。 在打开的对话框中勾选两个与数据适配器对应的复选框,并单击 OK 按钮。 这样创建了一个 DataSet 和两个对应于数据适配器提供的数据的 DataTable 对象。
现在可以通过所创建的数据集来引用 DataTables (使用 Categories 和 Products 名称)。 所创建的数据集的默认名称是 dataSet11。
如果在设计时刻创建 DataTables,则仍然需要编写代码使用数据库中的数据来装载表。 例如,在窗体的 Load 事件处理程序中,编写下列代码来执行此任务:
C# | 复制代码 |
---|---|
AdapterCategories.Fill(dataSet11, "Categories"); AdapterProducts.Fill(dataSet11, "Products"); |
Visual Basic | 复制代码 |
---|---|
AdapterCategories.Fill(dataSet11, "Categories") AdapterProducts.Fill(dataSet11, "Products") |
C# | 复制代码 |
---|---|
DataSet dataSet11 = new DataSet(); AdapterCategories.Fill(dataSet11, "Categories"); AdapterProducts.Fill(dataSet11, "Products"); |
Visual Basic | 复制代码 |
---|---|
Dim dataSet11 As DataSet = New DataSet 'Create DataTable objects for representing database's tables AdapterCategories.Fill(dataSet11, "Categories") AdapterProducts.Fill(dataSet11, "Products") |
3. 设置主/从关系
这样打开数据集的架构:
要创建关系,则单击主表中键字段的左侧,并拖动鼠标到相应的子表字段。 在本示例中,需要把 Categories 表的 CategoryID 字段拖动到 Products 表的 CategoryID 字段。 (注意,应选中 工具箱 中的 Relation 工具来允许这样操作)。 在停止拖动之后, Edit Relation 对话框将显示。 选项必须设置为下图中所示的那样:
按下 OK 按钮。 现在,数据集架构展示了一个在表间的“一对多”关系。
要通过代码设置主/从关系,则可以使用数据集组件的 Relations 属性,或使用主 DataTable 的 ChildRelations 属性:
C# | 复制代码 |
---|---|
DataColumn keyColumn = dataSet11.Tables["Categories"].Columns["CategoryID"]; DataColumn foreignKeyColumn = dataSet11.Tables["Products"].Columns["CategoryID"]; dataSet11.Relations.Add("CategoriesProducts", keyColumn, foreignKeyColumn); |
Visual Basic | 复制代码 |
---|---|
'Set up a master-detail relationship between the DataTables Dim keyColumn As DataColumn = dataSet11.Tables("Categories").Columns("CategoryID") Dim foreignKeyColumn As DataColumn = dataSet11.Tables("Products").Columns("CategoryID") dataSet11.Relations.Add("CategoriesProducts", keyColumn, foreignKeyColumn) |
4. 把 XtraGrid 绑定到主数据表
在本示例中,GridControl.DataSource 属性用于把网格控件连接到主 DataTable。 一旦数据源被指派到网格控件,则自动获取数据源中的字段,并在主视图中创建列:
注意,主视图中的行显示了展开按钮 (+),指明数据源包含主/从关系s
C# | 复制代码 |
---|---|
gridControl1.DataSource = dataSet11.Tables["Categories"];
gridControl1.ForceInitialize();
|
Visual Basic | 复制代码 |
---|---|
GridControl1.DataSource = dataSet11.Tables("Categories")
GridControl1.ForceInitialize()
|
GridControl.ForceInitialize 方法完成网格控件的初始化。 在窗体的 Load 事件处理程序中,在此方法被调用之后,就可以安全地访问主视图的列,以及操作视图的设置。
现在可以运行此应用程序。 当主控行被展开时,网格控件根据主表视图 (在这种情况下为主视图) 的设置创建细节视图。 细节视图被呈现为网格视图,因为主表视图是 GridView 类型。
5. 指定和定制呈现数据表的视图
层设计器展示了主表是由 XtraGrid 中的网格视图 (gridView1) 呈现的。 CategoriesProducts 关系没有与模式视图相关联,因为它的细节克隆视图使用网格视图呈现 (在这种情况下,细节克隆视图的模式由主表视图确定)。 要把一个视图指派到 CategoriesProducts 关系,则单击层名称框右侧的 Click here to change view(单击此处改变视图) 链接:
从菜单中选中 CardView 选项,使用 卡片视图 来呈现细节视图 (克隆)。 现在,层设计器的外观像这样:
要通过代码把模式视图指派到关系,则使用 GridControl.LevelTree 属性:
C# | 复制代码 |
---|---|
CardView cardView1 = new CardView(gridControl1); gridControl1.LevelTree.Nodes.Add("CategoriesProducts", cardView1); |
Visual Basic | 复制代码 |
---|---|
Dim cardView1 As CardView = New CardView(GridControl1) GridControl1.LevelTree.Nodes.Add("CategoriesProducts", cardView1) |
单击 Run Designer(运行设计器) 按钮打开网格控件的设计器。 在设计器顶部的 Selected View(已选中视图) 下拉列表中选中 cardView1 项。 然后可以使用设计器的页面来定制视图的选项。
切换到 “Columns(列)”页面 并单击 Retrieve Fields(取回字段) 按钮。 这样,取出绑定数据源中的字段,并在卡片视图中创建相应的列。
在取出列之后,就可以修改其设置。 我们把绑定到 CategoryID 字段的列隐藏掉。 在 Columns 页面中,从列的列表选中 colCategoryID1 列,并把它的 VisibleIndex 属性设置为 -1:
要改变主表视图的列设置,则首先从 Selected View 的下拉列表中选择 gridView1 项。 然后切换到 Column 页面,在其中修改列的设置。
要通过代码从数据源获取列,则使用重载的 BaseView.PopulateColumns 方法。 对于主视图,可以调用没有参数的 BaseView.PopulateColumns 方法。 对于模式视图,则应该调用数据源作为参数的 BaseView.PopulateColumns 方法的重载。
注意,在我们的示例中,不需要为主视图调用 BaseView.PopulateColumns。 当网格控件被绑定到数据源时,列已经被自动创建,并且 GridControl.ForceInitialize 方法已经被调用。
C# | 复制代码 |
---|---|
//Hide the CategoryID column from the master view gridView1.Columns["CategoryID"].VisibleIndex = -1; //Create columns for the pattern view cardView1.PopulateColumns(dataSet11.Tables["Products"]); //Hide the CategoryID column from the pattern view cardView1.Columns["CategoryID"].VisibleIndex = -1; |
Visual Basic | 复制代码 |
---|---|
'Hide the CategoryID column from the master view GridView1.Columns("CategoryID").VisibleIndex = -1 'Create columns for the pattern view cardView1.PopulateColumns(dataSet11.Tables("Products")) 'Hide the CategoryID column from the pattern view cardView1.Columns("CategoryID").VisibleIndex = -1 |
为了定制细节视图的外观,我们将通过 “Style Schemes(样式方案)”页面 加载预定义的配色方案。 在网格设计器中,切换到 Style Schemes(样式方案) 页面,并在 Formats 列表中选中 Winter 项。 把 Paint Style(绘制样式) 组合框的取值设置为 MixedXP,以避免在绘制列标头、指示器面板和其他某些元素时使用 Windows XP 主题。
单击 Apply 按钮。
在运行时刻使用下面的代码把配色方案应用于主视图:
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Design; //Set a predefined color scheme for the Card View //Color schemes are stored in the Windows\System32 folder by default //in the DevExpress.XtraGrid.Appearances.xml file string filePath = System.Environment.GetFolderPath( System.Environment.SpecialFolder.System) + "\\DevExpress.XtraGrid.Appearances.xml"; XAppearances xAppearances = new XAppearances(filePath); xAppearances.LoadScheme("Winter", cardView1); cardView1.PaintStyleName = "MixedXP"; |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Design 'Set a predefined color scheme for the Card View 'Color schemes are stored in the Windows\System32 folder by default 'in the DevExpress.XtraGrid.Appearances.xml file Dim filePath As String = System.Environment.GetFolderPath( _ System.Environment.SpecialFolder.System) + "\DevExpress.XtraGrid.Appearances.xml" Dim xAppearances As XAppearances = New XAppearances(filePath) xAppearances.LoadScheme("Winter", cardView1) CardView1.PaintStyleName = "MixedXP" |
请参阅 样式方案 主题获取关于在 XtraGrid 中使用配色方案的其他信息。
使用相同的方式,可以把特定的样式方案应用于主表视图。
完整代码
C# | 复制代码 |
---|---|
using DevExpress.XtraGrid.Views.Card; using DevExpress.XtraGrid.Design; private void Form1_Load(object sender, System.EventArgs e) { //Define a connection to the database OleDbConnection connection = new OleDbConnection( "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\\Data\\nwind.mdb"); //Create data adapters for retrieving data from the tables OleDbDataAdapter AdapterCategories = new OleDbDataAdapter( "SELECT CategoryID, CategoryName, Picture FROM Categories", connection); OleDbDataAdapter AdapterProducts = new OleDbDataAdapter( "SELECT CategoryID, ProductID, ProductName, UnitPrice FROM Products", connection); DataSet dataSet11 = new DataSet(); //Create DataTable objects for representing database's tables AdapterCategories.Fill(dataSet11, "Categories"); AdapterProducts.Fill(dataSet11, "Products"); //Set up a master-detail relationship between the DataTables DataColumn keyColumn = dataSet11.Tables["Categories"].Columns["CategoryID"]; DataColumn foreignKeyColumn = dataSet11.Tables["Products"].Columns["CategoryID"]; dataSet11.Relations.Add("CategoriesProducts", keyColumn, foreignKeyColumn); //Bind the grid control to the data source gridControl1.DataSource = dataSet11.Tables["Categories"]; gridControl1.ForceInitialize(); //Assign a CardView to the relationship CardView cardView1 = new CardView(gridControl1); gridControl1.LevelTree.Nodes.Add("CategoriesProducts", cardView1); //Hide the CategoryID column for the master view gridView1.Columns["CategoryID"].VisibleIndex = -1; //Create columns for the pattern view cardView1.PopulateColumns(dataSet11.Tables["Products"]); //Hide the CategoryID column for the pattern view cardView1.Columns["CategoryID"].VisibleIndex = -1; //Set a predefined color scheme for the Card View //Color schemes are stored in the Windows\System32 folder by default //in the DevExpress.XtraGrid.Appearances.xml file string filePath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.System) + "\\DevExpress.XtraGrid.Appearances.xml"; XAppearances xAppearances = new XAppearances(filePath); xAppearances.LoadScheme("Winter", cardView1); cardView1.PaintStyleName = "MixedXP"; xAppearances.LoadScheme("Winter", gridView1); gridView1.PaintStyleName = "MixedXP"; } |
Visual Basic | 复制代码 |
---|---|
Imports DevExpress.XtraGrid.Views.Card Imports DevExpress.XtraGrid.Design Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) _ Handles MyBase.Load 'Define a connection to the database Dim connection As OleDbConnection = New OleDbConnection( _ "Provider=Microsoft.Jet.OLEDB.4.0;Data Source = C:\Data\nwind.mdb") 'Create data adapters for retrieving data from the tables Dim AdapterCategories As OleDbDataAdapter = New OleDbDataAdapter( _ "SELECT CategoryID, CategoryName, Picture FROM Categories", connection) Dim AdapterProducts As OleDbDataAdapter = New OleDbDataAdapter( _ "SELECT CategoryID, ProductID, ProductName, UnitPrice FROM Products", connection) Dim dataSet11 As DataSet = New DataSet 'Create DataTable objects for representing database's tables AdapterCategories.Fill(dataSet11, "Categories") AdapterProducts.Fill(dataSet11, "Products") 'Set up a master-detail relationship between the DataTables Dim keyColumn As DataColumn = dataSet11.Tables("Categories").Columns("CategoryID") Dim foreignKeyColumn As DataColumn = dataSet11.Tables("Products").Columns("CategoryID") dataSet11.Relations.Add("CategoriesProducts", keyColumn, foreignKeyColumn) 'Bind the grid control to the data source GridControl1.DataSource = dataSet11.Tables("Categories") GridControl1.ForceInitialize() 'Assign a CardView to the relationship Dim cardView1 As CardView = New CardView(GridControl1) GridControl1.LevelTree.Nodes.Add("CategoriesProducts", cardView1) 'Hide the CategoryID column for the master view GridView1.Columns("CategoryID").VisibleIndex = -1 'Create columns for the pattern view cardView1.PopulateColumns(dataSet11.Tables("Products")) 'Hide the CategoryID column for the pattern view cardView1.Columns("CategoryID").VisibleIndex = -1 'Set a predefined color scheme for the Card View 'Color schemes are stored in the Windows\System32 folder by default 'in the DevExpress.XtraGrid.Appearances.xml file Dim filePath As String = System.Environment.GetFolderPath( _ System.Environment.SpecialFolder.System) + _ "\DevExpress.XtraGrid.Appearances.xml" Dim xAppearances As XAppearances = New XAppearances(filePath) xAppearances.LoadScheme("Winter", cardView1) CardView1.PaintStyleName = "MixedXP" xAppearances.LoadScheme("Winter", GridView1) GridView1.PaintStyleName = "MixedXP" End Sub |
下面的屏幕截图展示了网格定制的结果:
要获得更复杂的为 DataTables 实现主/从模式的示例,请参阅 Master-Detail 演示,此演示可以在安装包中找到。