演练:构造数据驱动的动态布局
Windows Presentation Foundation (WPF) 提供的控件支持数据驱动的动态布局。 通过在 适用于 Visual Studio 的 WPF 设计器中使用这些控件,可以轻松创建这些类型的布局。 您可以在应用程序中使用下列控件:
ListView 控件提供了一个基础结构,用于在不同的布局中显示一组数据项。 通常,可以结合使用 GridView 和 ListView 控件以便在列中显示数据。 有关更多信息,请参见 ListView 概述和 GridView 概述。
在本演练中,您将执行下列任务:
准备一个数据源。
创建一个 WPF 应用程序。
配置默认的 Grid Panel 控件。
添加和配置一个 ListView 控件。
在 XAML 中添加和配置一个 GridView。
添加和配置一个 Button 控件。
添加数据绑定代码。
测试应用程序。
下面的插图说明您的应用程序将如何显示。
提示
显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您现用的设置或版本。 若要更改设置,请在“工具”菜单上选择“导入和导出设置”。 有关更多信息,请参见 使用设置。
系统必备
您需要以下组件来完成本演练:
- Visual Studio 2010
准备数据源
对于本演练,将需要一个要绑定到的示例数据源。 您将创建一个简单的 CSV 文件数据源。
准备数据源
创建一个新文件夹,并将其命名为 Data。
在 Data 文件夹中,创建一个新的文本文件,并将其命名为 employees.csv。
提示
可以使用任何文本编辑器(例如记事本)来创建文件。
向文本文件中添加以下内容:
LastName,FirstName,Title Davis,Sara,Sales Representative Funk,Don,Vice President, Sales Levin,Danny,Sales Representative Penor,Lori,Sales Representative Buschmann,Monika,Sales Manager Suominen,Ari,Sales Representative King,Russell,Sales Representative Cameron,Maria,Inside Sales Coordinator Doyle,Patricia,Sales Representative
保存并关闭文件。
提示
可在 Excel 中打开文件,并确认以逗号分隔的数据显示在单独的列中。
在 Data 文件夹中,创建一个新的文本文件,并将其命名为 schema.ini。 该架构文件描述数据文件夹中的文本文件的格式。
向文本文件中添加以下内容:
[employees.csv] Format=CSVDelimited ColNameHeader=True
提示
在本演练中,您的 CSV 文件具有列标题。 若要绑定到没有列标题的 CSV 文件,请将 ColNameHeader=True 更改为 ColNameHeader=False。
保存并关闭文件。
创建项目
下一个过程是为该应用程序创建 Visual Studio 项目。
创建项目
使用 Visual Basic 或 Visual C# 创建一个名为 DataDrivenLayout 的新 WPF 应用程序项目。 有关更多信息,请参见如何:创建新的 WPF 应用程序项目。
MainWindow.xaml 将在 WPF 设计器中打开。
在**“文件”菜单上,单击“全部保存”**。
配置默认的 Grid Panel 控件
默认情况下,新的 WPF 应用程序包含一个带有 Grid 面板的 Window。 在此过程中,您将向该网格中添加两行。 您将其中一行的高度设置为 Auto,以便该行的大小与内容相符。 您将另一行的高度设置为 *,以便该行使用剩余的可用高度。
配置默认的 Grid Panel 控件
在“设计”视图中选择 Grid。 有关更多信息,请参见如何:在设计图面上选择和移动元素。
在**“属性”**窗口中,找到 RowDefinitions 属性,并单击“属性值”列中的省略号按钮。
此时将会显示**“集合编辑器”**。
单击两次**“添加”**添加两行。
将第一行的 Height 属性设置为 *。
将第二行的 Height 属性设置为 Auto。
单击**“确定”以关闭“集合编辑器”**并返回到 WPF 设计器。
现在该网格中有两行,但仅有一行显示。 其 Height 属性被设置为 Auto 的行会暂时隐藏,因为它没有任何内容。 对于本演练,这样是可以的。 为了避免将来出现这种情况,您可以在工作时使用星号调整大小,然后在完成后改成“Auto”。
在**“文件”菜单上,单击“全部保存”**。
添加和配置 ListView
在此过程中,您将添加一个 ListView。 您将为 ListView 提供一个名称,这样便可在代码隐藏文件中引用它。 还将为其配置布局属性。
添加和配置 ListView
在“设计”视图中选择 Grid。
在**“属性”**窗口中,设置 ListView 的下列属性:
Property
值
名称
lvEmployees
Grid.Column
0
Grid.ColumnSpan
1
Grid.Row
0
Grid.RowSpan
1
宽度
Auto
高度
Auto
HorizontalAlignment
Stretch
VerticalAlignment
Stretch
Margin
0
在**“文件”菜单上,单击“全部保存”**。
添加和配置 GridView
在此过程中,您将添加一个具有三列的 GridView,以显示文本文件中的数据。 由于您要在代码隐藏文件中引用这些列以将数据分别绑定到列,因此您将为这些列提供名称。 有关更多信息,请参见如何:使用 GridView 显示 ListView 内容。
添加和配置 GridView
在 XAML 编辑器中找到 ListView 元素。 该元素如下所示:
<ListView <ATTRIBUTES> />
提示
为了便于在 XAML 视图中突出显示元素,可单击“设计”视图中的控件或者使用“文档大纲”窗口。
用下面的内容替换 ListView 元素:
<ListView x:Name="lvEmployees"> <ListView.View> <GridView AllowsColumnReorder="True"> <GridViewColumn x:Name="c1Employees" Header="Last Name"></GridViewColumn> <GridViewColumn x:Name="c2Employees" Header="First Name"></GridViewColumn> <GridViewColumn x:Name="c3Employees" Header="Title"></GridViewColumn> </GridView> </ListView.View> </ListView>
在**“文件”菜单上,单击“全部保存”**。
添加和配置 Button
在此过程中,您将添加一个 Button 并指定其 Click 事件。
添加和配置 Button
在“设计”视图中选择 Grid。
在**“属性”**窗口中,设置 Button 的下列属性:
Property
值
名称
btnGetData
Content
Get Data
Grid.Column
0
Grid.ColumnSpan
1
Grid.Row
1
Grid.RowSpan
1
宽度
75
高度
23
HorizontalAlignment
向右
VerticalAlignment
Bottom
Margin
5
在 XAML 编辑器中找到 Button 元素。 该元素如下所示:
<Button <ATTRIBUTES>>Button</Button>
提示
为了便于在 XAML 视图中突出显示元素,可单击“设计”视图中的控件或者使用“文档大纲”窗口。
编辑 XAML 以添加 Click 事件特性。 其外观应类似于:
<Button Click="btnGetData_Click" <ATTRIBUTES>>Button</Button>
在**“文件”菜单上,单击“全部保存”**。
添加数据绑定代码
在此过程中,您将为 Button 的 Click 事件添加代码。 在运行时单击该按钮,以获取数据并将其绑定到 ListView 和 GridView。
添加数据绑定代码
打开代码隐藏文件 MainWindow.xaml.cs 或 MainWindow.xaml.vb,具体取决于您为项目选择的语言。
在代码编辑器的顶部,添加以下代码。 目的是为了绑定到访问 System.Data 和 System.Data.OleDb 命名空间所需的数据。
Imports System.Data 'DataTable Imports System.Data.OleDb 'OleDbDataAdapter Imports System.Windows 'RoutedEventArgs Imports System.Windows.Data 'Binding Imports System.Windows.Controls 'ListView
using System; //Exception using System.Data; //DataTable using System.Data.OleDb; //OleDbDataAdapter using System.Windows; //RoutedEventArgs using System.Windows.Data; //Binding using System.Windows.Controls; //ListView
在 MainWindow 类中添加以下代码。 使用 DataTable 来存储数据。
Dim dtEmployees As DataTable
DataTable dtEmployees;
在 MainWindow 类中添加以下代码。 当用户单击该按钮时,您将获取数据,然后将其绑定到 ListView。
Private Sub btnGetData_Click(ByVal sender As Object, ByVal e As RoutedEventArgs) dtEmployees = GetData() BindData() End Sub
private void btnGetData_Click(object sender, RoutedEventArgs e) { dtEmployees = GetData(); BindData(); }
在 MainWindow 类中,添加以下代码并指定 Data 文件夹的路径。 若要获取数据,可以使用 OleDbDataAdapter。
Function GetData() As DataTable Dim sConnection As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<Your Path>\Data\;Extended Properties=""text;HDR=yes;FMT=delimited"";" Dim sSQL As String = "select * from employees.csv" Dim dt As DataTable = New DataTable() Dim da As OleDbDataAdapter = New OleDbDataAdapter(sSQL, sConnection) Try da.Fill(dt) Catch ex As Exception MessageBox.Show(ex.ToString()) End Try Return dt End Function
DataTable GetData() { string sConnection = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=<Your Path>\\Data\\;Extended Properties=\"text;HDR=yes;FMT=delimited\";"; string sSQL = "select * from employees.csv"; DataTable dt = new DataTable(); OleDbDataAdapter da = new OleDbDataAdapter(sSQL, sConnection); try { da.Fill(dt); } catch (Exception e) { MessageBox.Show(e.ToString()); } return dt; }
在 MainWindow 类中添加以下代码。 若要将数据绑定到 ListView,可以将其 DataContext 设置为 DataTable。 将在 GridView 的列中显示数据列。
Sub BindData() lvEmployees.DataContext = dtEmployees lvEmployees.SetBinding(ListView.ItemsSourceProperty, New Binding()) c1Employees.DisplayMemberBinding = New Binding("LastName") c2Employees.DisplayMemberBinding = New Binding("FirstName") c3Employees.DisplayMemberBinding = New Binding("Title") End Sub
void BindData() { lvEmployees.DataContext = dtEmployees; lvEmployees.SetBinding(ListView.ItemsSourceProperty, new Binding()); c1Employees.DisplayMemberBinding = new Binding("LastName"); c2Employees.DisplayMemberBinding = new Binding("FirstName"); c3Employees.DisplayMemberBinding = new Binding("Title"); }
在**“文件”菜单上,单击“全部保存”**。
将窗口设置为动态调整大小
SizeToContent 属性指定当其内容的大小更改时 Window 的大小如何更改。 默认情况下,此属性设置为 Manual,表示用户可以手动调整窗口的大小以适应内容。 在此过程中,您将此属性设置为 WidthAndHeight,这表示在窗口中的内容更改时窗口会动态调整大小。
将窗口设置为动态调整大小
在设计器中打开 MainWindow.xaml。
在“设计”视图中选择 Window。
在**“属性”**窗口中,设置 Window 的下列属性:
Property
值
SizeToContent
WidthAndHeight
宽度
Auto
高度
Auto
在**“文件”菜单上,单击“全部保存”**。
测试应用程序
测试应用程序
在**“调试”菜单上,单击“启动调试”**。
该应用程序启动并且该窗口将显示。 由于您将 SizeToContent 属性设置为 WidthAndHeight,因此窗口的大小只能容纳 GridView 标题和 Button。
单击**“获取数据”**。
应用程序将获取数据并将其绑定到 GridView。 GridView、ListView 和 Window 都会动态调整大小以适应新内容。
关闭该窗口。
汇总所有内容
下面是完成的 MainWindow.xaml 文件:
<Window x:Class="MainWindow"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="Auto" Width="Auto" SizeToContent="WidthAndHeight">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView x:Name="lvEmployees">
<ListView.View>
<GridView AllowsColumnReorder="True">
<GridViewColumn x:Name="c1Employees" Header="Last Name"></GridViewColumn>
<GridViewColumn x:Name="c2Employees" Header="First Name"></GridViewColumn>
<GridViewColumn x:Name="c3Employees" Header="Title"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Button Click="btnGetData_Click" Name="btnGetData" Margin="5" Height="23" Width="75" HorizontalAlignment="Right" VerticalAlignment="Bottom" Grid.Column="0" Grid.ColumnSpan="1" Grid.Row="1" Grid.RowSpan="1">Get Data</Button>
</Grid>
</Window>
后续步骤
在此演练中,您使用具有三列的 GridView 来显示数据。 您直接将数据分别绑定到每个列。 您也可以使用数据模板在 ListView 或 GridView 中排列数据并设置其样式。 有关更多信息,请参见数据模板化概述。
可以使用此演练中的数据模板进行试验。 例如,可以创建类似如下的模板:
<Window.Resources>
<DataTemplate x:Key="templateEmployees">
<Border BorderBrush="Silver" BorderThickness="1" Padding="5" Margin="5">
<DockPanel>
<StackPanel DockPanel.Dock="Left">
<TextBlock Text="{Binding Path=LastName}" />
<TextBlock Text="{Binding Path=FirstName}" />
</StackPanel>
<TextBlock Text="{Binding Path=Title}" DockPanel.Dock="Right" />
</DockPanel>
</Border>
</DataTemplate>
</Window.Resources>
然后在 GridView 中将该数据模板与以下代码一起使用:
<ListView.View>
<GridView>
<GridViewColumn CellTemplate="{StaticResource templateEmployees}" />
</GridView>
</ListView.View>
从代码隐藏文件中移除或注释以下代码:
c1Employees.DisplayMemberBinding = New Binding("LastName")
c2Employees.DisplayMemberBinding = New Binding("FirstName")
c3Employees.DisplayMemberBinding = New Binding("Title")
c1Employees.DisplayMemberBinding = new Binding("LastName");
c2Employees.DisplayMemberBinding = new Binding("FirstName");
c3Employees.DisplayMemberBinding = new Binding("Title");
请参见
任务
概念
WPF and Silverlight Designer 概述