演练:构造数据驱动的动态布局

Windows Presentation Foundation (WPF) 提供的控件支持数据驱动的动态布局。 通过在 适用于 Visual Studio 的 WPF 设计器中使用这些控件,可以轻松创建这些类型的布局。 您可以在应用程序中使用下列控件:

ListView 控件提供了一个基础结构,用于在不同的布局中显示一组数据项。 通常,可以结合使用 GridViewListView 控件以便在列中显示数据。 有关更多信息,请参见 ListView 概述GridView 概述

在本演练中,您将执行下列任务:

  • 准备一个数据源。

  • 创建一个 WPF 应用程序。

  • 配置默认的 Grid Panel 控件。

  • 添加和配置一个 ListView 控件。

  • 在 XAML 中添加和配置一个 GridView

  • 添加和配置一个 Button 控件。

  • 添加数据绑定代码。

  • 测试应用程序。

下面的插图说明您的应用程序将如何显示。

数据驱动的动态布局

提示

显示的对话框和菜单命令可能会与“帮助”中的描述不同,具体取决于您现用的设置或版本。 若要更改设置,请在“工具”菜单上选择“导入和导出设置”。 有关更多信息,请参见 使用设置

系统必备

您需要以下组件来完成本演练:

  • Visual Studio 2010

准备数据源

对于本演练,将需要一个要绑定到的示例数据源。 您将创建一个简单的 CSV 文件数据源。

准备数据源

  1. 创建一个新文件夹,并将其命名为 Data。

  2. 在 Data 文件夹中,创建一个新的文本文件,并将其命名为 employees.csv。

    提示

    可以使用任何文本编辑器(例如记事本)来创建文件。

  3. 向文本文件中添加以下内容:

    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
    
  4. 保存并关闭文件。

    提示

    可在 Excel 中打开文件,并确认以逗号分隔的数据显示在单独的列中。

  5. 在 Data 文件夹中,创建一个新的文本文件,并将其命名为 schema.ini。 该架构文件描述数据文件夹中的文本文件的格式。

  6. 向文本文件中添加以下内容:

    [employees.csv]
    Format=CSVDelimited
    ColNameHeader=True
    

    提示

    在本演练中,您的 CSV 文件具有列标题。 若要绑定到没有列标题的 CSV 文件,请将 ColNameHeader=True 更改为 ColNameHeader=False。

  7. 保存并关闭文件。

创建项目

下一个过程是为该应用程序创建 Visual Studio 项目。

创建项目

  1. 使用 Visual Basic 或 Visual C# 创建一个名为 DataDrivenLayout 的新 WPF 应用程序项目。 有关更多信息,请参见如何:创建新的 WPF 应用程序项目

    MainWindow.xaml 将在 WPF 设计器中打开。

  2. 在**“文件”菜单上,单击“全部保存”**。

配置默认的 Grid Panel 控件

默认情况下,新的 WPF 应用程序包含一个带有 Grid 面板的 Window。 在此过程中,您将向该网格中添加两行。 您将其中一行的高度设置为 Auto,以便该行的大小与内容相符。 您将另一行的高度设置为 *,以便该行使用剩余的可用高度。

配置默认的 Grid Panel 控件

  1. 在“设计”视图中选择 Grid。 有关更多信息,请参见如何:在设计图面上选择和移动元素

  2. 在**“属性”**窗口中,找到 RowDefinitions 属性,并单击“属性值”列中的省略号按钮。

    此时将会显示**“集合编辑器”**。

  3. 单击两次**“添加”**添加两行。

  4. 将第一行的 Height 属性设置为 *。

  5. 将第二行的 Height 属性设置为 Auto。

  6. 单击**“确定”以关闭“集合编辑器”**并返回到 WPF 设计器。

    现在该网格中有两行,但仅有一行显示。 其 Height 属性被设置为 Auto 的行会暂时隐藏,因为它没有任何内容。 对于本演练,这样是可以的。 为了避免将来出现这种情况,您可以在工作时使用星号调整大小,然后在完成后改成“Auto”。

  7. 在**“文件”菜单上,单击“全部保存”**。

添加和配置 ListView

在此过程中,您将添加一个 ListView。 您将为 ListView 提供一个名称,这样便可在代码隐藏文件中引用它。 还将为其配置布局属性。

添加和配置 ListView

  1. 在“设计”视图中选择 Grid

  2. 从**“工具箱”中的“控件”**组中将一个 ListView 控件拖动到 Grid 上。

  3. 在**“属性”**窗口中,设置 ListView 的下列属性:

    Property

    名称

    lvEmployees

    Grid.Column

    0

    Grid.ColumnSpan

    1

    Grid.Row

    0

    Grid.RowSpan

    1

    宽度

    Auto

    高度

    Auto

    HorizontalAlignment

    Stretch

    VerticalAlignment

    Stretch

    Margin

    0

  4. 在**“文件”菜单上,单击“全部保存”**。

添加和配置 GridView

在此过程中,您将添加一个具有三列的 GridView,以显示文本文件中的数据。 由于您要在代码隐藏文件中引用这些列以将数据分别绑定到列,因此您将为这些列提供名称。 有关更多信息,请参见如何:使用 GridView 显示 ListView 内容

添加和配置 GridView

  1. 在 XAML 编辑器中找到 ListView 元素。 该元素如下所示:

    <ListView <ATTRIBUTES> />
    

    提示

    为了便于在 XAML 视图中突出显示元素,可单击“设计”视图中的控件或者使用“文档大纲”窗口。

  2. 用下面的内容替换 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>
    
  3. 在**“文件”菜单上,单击“全部保存”**。

添加和配置 Button

在此过程中,您将添加一个 Button 并指定其 Click 事件。

添加和配置 Button

  1. 在“设计”视图中选择 Grid

    提示

    由于 ListView 覆盖了 Grid,因此可能很难选择 Grid。 可以使用 Tab 键或“文档大纲”窗口来选择 Grid

  2. 从**“工具箱”中的“控件”**组中将一个 Button 控件拖动到 Grid 上。

  3. 在**“属性”**窗口中,设置 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

  4. 在 XAML 编辑器中找到 Button 元素。 该元素如下所示:

    <Button <ATTRIBUTES>>Button</Button>
    

    提示

    为了便于在 XAML 视图中突出显示元素,可单击“设计”视图中的控件或者使用“文档大纲”窗口。

  5. 编辑 XAML 以添加 Click 事件特性。 其外观应类似于:

    <Button Click="btnGetData_Click" <ATTRIBUTES>>Button</Button>
    
  6. 在**“文件”菜单上,单击“全部保存”**。

添加数据绑定代码

在此过程中,您将为 ButtonClick 事件添加代码。 在运行时单击该按钮,以获取数据并将其绑定到 ListViewGridView

添加数据绑定代码

  1. 打开代码隐藏文件 MainWindow.xaml.cs 或 MainWindow.xaml.vb,具体取决于您为项目选择的语言。

  2. 在代码编辑器的顶部,添加以下代码。 目的是为了绑定到访问 System.DataSystem.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
    
  3. 在 MainWindow 类中添加以下代码。 使用 DataTable 来存储数据。

    Dim dtEmployees As DataTable
    
    DataTable dtEmployees;
    
  4. 在 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();
    }
    
  5. 在 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;
    }
    
  6. 在 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");
    }
    
  7. 在**“文件”菜单上,单击“全部保存”**。

将窗口设置为动态调整大小

SizeToContent 属性指定当其内容的大小更改时 Window 的大小如何更改。 默认情况下,此属性设置为 Manual,表示用户可以手动调整窗口的大小以适应内容。 在此过程中,您将此属性设置为 WidthAndHeight,这表示在窗口中的内容更改时窗口会动态调整大小。

将窗口设置为动态调整大小

  1. 在设计器中打开 MainWindow.xaml。

  2. 在“设计”视图中选择 Window

  3. 在**“属性”**窗口中,设置 Window 的下列属性:

    Property

    SizeToContent

    WidthAndHeight

    宽度

    Auto

    高度

    Auto

  4. 在**“文件”菜单上,单击“全部保存”**。

测试应用程序

测试应用程序

  1. 在**“调试”菜单上,单击“启动调试”**。

    该应用程序启动并且该窗口将显示。 由于您将 SizeToContent 属性设置为 WidthAndHeight,因此窗口的大小只能容纳 GridView 标题和 Button

  2. 单击**“获取数据”**。

    应用程序将获取数据并将其绑定到 GridViewGridViewListViewWindow 都会动态调整大小以适应新内容。

  3. 关闭该窗口。

汇总所有内容

下面是完成的 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 来显示数据。 您直接将数据分别绑定到每个列。 您也可以使用数据模板在 ListViewGridView 中排列数据并设置其样式。 有关更多信息,请参见数据模板化概述

可以使用此演练中的数据模板进行试验。 例如,可以创建类似如下的模板:

<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 概述

其他资源

布局演练

使用 WPF 设计器