本文档说明如何使用由数据源提供的方法,为 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,则仍然需要编写代码使用数据库中的数据来装载表。 例如,在窗体的 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. 设置主/从关系
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. 指定和定制呈现数据表的视图
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 项。 然后可以使用设计器的页面来定制视图的选项。
在取出列之后,就可以修改其设置。 我们把绑定到 CategoryID 字段的列隐藏掉。 在 Columns 页面中,从列的列表选中 colCategoryID1 列,并把它的 VisibleIndex 属性设置为 -1:
要通过代码从数据源获取列,则使用重载的 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 主题。
在运行时刻使用下面的代码把配色方案应用于主视图:
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 |
下面的屏幕截图展示了网格定制的结果: