演练:开始使用 WPF
更新:2010 年 12 月
本演练介绍了一个 Windows Presentation Foundation (WPF) 应用程序的开发,该应用程序包括多数 WPF 应用程序所共有的元素,即Extensible Application Markup Language (XAML) 标记、代码隐藏、应用程序定义、控件、布局、数据绑定和样式。
本演练引导您通过以下步骤完成一个简单的 WPF 应用程序的开发。
定义 XAML 以设计应用程序的user interface (UI) 的外观。
编写代码以生成应用程序的行为。
创建应用程序定义以管理应用程序。
添加控件和创建布局以构成应用程序 UI。
创建样式,以便为整个应用程序的 UI 创建一致的外观。
将 UI 绑定到数据,以便既可以用数据填充 UI,又可以使数据和 UI 保持同步。
在本演练结束时,您便会生成好一个独立的 Windows 应用程序,使用此应用程序,用户可以查看选定人员的零用金报销单。 应用程序由若干在浏览器样式的窗口中承载的 WPF 页组成。
用于生成此演练的代码示例同时适用于 Microsoft Visual Basic 和 C#,并可在 Introduction to Building WPF Applications(生成 WPF 应用程序简介)中找到。
在本节中,您将创建应用程序基础结构,其中包括一个应用程序定义、两个页以及一个图像。
在 Visual Basic 或 Visual C# 中新建一个名为 ExpenseIt 的 WPF 应用程序项目。 有关更多信息,请参见如何:创建新的 WPF 应用程序项目。
注意 本演练使用在 .NET Framework 4 中可用的 DataGrid 控件。 请确保项目以 .NET Framework 4 为目标。 有关更多信息,请参见如何:面向特定的 .NET Framework 版本或配置文件。
打开 Application.xaml (Visual Basic) 或 App.xaml (C#)。
此 XAML 文件定义 WPF 应用程序和任何应用程序资源。也可以使用此文件来指定在应用程序启动时自动显示的 UI;本例中为 MainWindow.xaml。
XAML 在 Visual Basic 中应如下所示:
<Application x:Class="Application" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> </Application.Resources> </Application>
或者,在 C# 中应如下所示:
<Application x:Class="ExpenseIt.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> <Application.Resources> </Application.Resources> </Application>
打开 MainWindow.xaml。
此 XAML 文件是应用程序的主窗口,并显示在页中创建的内容。 Window 类定义窗口的属性(例如标题、大小或图标)并处理事件(例如关闭或隐藏)。
将 Window 元素更改为 NavigationWindow。
此应用程序将导航到不同的内容,具体情况视用户交互而定。 因此,需要将主 Window 更改为 NavigationWindow。NavigationWindow 继承 Window 的所有属性。 XAML 文件中的 NavigationWindow 元素创建 NavigationWindow 类的实例。 有关更多信息,请参见导航概述。
更改 NavigationWindow 元素上的以下属性:
将 Title 属性设置为“ExpenseIt”。
将 Width 属性设置为 500 像素。
将 Height 属性设置为 350 像素。
移除 NavigationWindow 标记之间的 Grid 元素。
XAML 在 Visual Basic 中应如下所示:
<NavigationWindow x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="ExpenseIt" Height="350" Width="500"> </NavigationWindow>
或者,在 C# 中应如下所示:
<NavigationWindow x:Class="ExpenseIt.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="ExpenseIt" Height="350" Width="500"> </NavigationWindow>
打开 MainWindow.xaml.vb 或 MainWindow.xaml.cs。
此文件为代码隐藏文件,其中包含用于处理 MainWindow.xaml 中声明的事件的代码。 此文件包含 XAML 中定义的窗口的分部类。
如果要使用 C#,请将 MainWindow 类更改为从 NavigationWindow 中派生。
在 Visual Basic 中,当您在 XAML 中更改窗口时,此操作将自动进行。
您的代码应如下所示。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace ExpenseIt { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : NavigationWindow { public MainWindow() { InitializeComponent(); } } }
在本节中,将向应用程序中添加两个页和一个图像。
向项目中添加一个名为 ExpenseItHome.xaml 的新页 (WPF)。 有关更多信息,请参见如何:向 WPF 项目中添加新项。
此页是应用程序启动时显示的第一页。 它将显示一个人员列表,用户可从中选择人员来显示其零用金报销单。
打开 ExpenseItHome.xaml。
将 Title 设置为“ExpenseIt - Home”。
XAML 在 Visual Basic 中应如下所示:
<Page x:Class="ExpenseItHome" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="ExpenseIt - Home"> <Grid> </Grid> </Page>
或者,在 C# 中应如下所示:
<Page x:Class="ExpenseIt.ExpenseItHome" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="ExpenseIt - Home"> <Grid> </Grid> </Page>
打开 MainWindow.xaml。
将 NavigationWindow 上的 Source 属性设置为“ExpenseItHome.xaml”。
这会将 ExpenseItHome.xaml 设置为应用程序启动时打开的第一页。 XAML 在 Visual Basic 中应如下所示:
<NavigationWindow x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml"> </NavigationWindow>
或者,在 C# 中应如下所示:
<NavigationWindow x:Class="ExpenseIt.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml"> </NavigationWindow>
向项目中添加一个名为 ExpenseReportPage.xaml 的新页 (WPF)。
此页将显示 ExpenseItHome.xaml 中所选人员的零用金报销单。
打开 ExpenseReportPage.xaml。
将 Title 设置为“ExpenseIt - View Expense”。
XAML 在 Visual Basic 中应如下所示:
<Page x:Class="ExpenseReportPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="ExpenseIt - View Expense"> <Grid> </Grid> </Page>
或者,在 C# 中应如下所示:
<Page x:Class="ExpenseIt.ExpenseReportPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300" Title="ExpenseIt - View Expense"> <Grid> </Grid> </Page>
打开 ExpenseItHome.xaml.vb 和 ExpenseReportPage.xaml.vb,或打开 ExpenseItHome.xaml.cs 和 ExpenseReportPage.xaml.cs。
当您创建新的页文件时,Visual Studio 将自动创建代码隐藏文件。 这些代码隐藏文件处理用于响应用户输入的逻辑。
您的代码应如下所示。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace ExpenseIt { ///<summary>/// Interaction logic for ExpenseItHome.xaml///</summary>publicpartialclass ExpenseItHome : Page { public ExpenseItHome() { InitializeComponent(); } } }
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace ExpenseIt { ///<summary>/// Interaction logic for ExpenseReportPage.xaml///</summary>publicpartialclass ExpenseReportPage : Page { public ExpenseReportPage() { InitializeComponent(); } } }
向项目中添加一个名为 watermark.png 的图像。 可以创建自己的图像,也可以从代码示例中复制文件。 有关更多信息,请参见如何:向项目添加现有项。
在本节中,您将生成和运行应用程序。
通过按 F5 或从“调试”菜单中选择“启动调试”来生成和运行应用程序。
下图显示带有 NavigationWindow 按钮的应用程序。
关闭应用程序以返回到 Visual Studio。
布局提供了放置 UI 元素的一种有序方法,并在 UI 调整大小时管理这些元素的大小和位置。 通常,将创建具有以下布局控件之一的布局:
其中每个布局控件都支持一种适用于其子元素的特殊布局类型。 ExpenseIt 页面可以调整大小,并且每个页面都具有沿其他元素水平和垂直排列的元素。 因此,Grid 是应用程序的理想布局元素。
在本节中,您将通过向 ExpenseItHome.xaml 中的 Grid 中添加列和行定义,来创建一个三行一列、边距为 10 像素的表。
打开 ExpenseItHome.xaml。
在 Grid 标记之间添加以下 XAML 以创建行和列定义。
<Grid.ColumnDefinitions> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions>
两个行的 Height 设置为 Auto,这意味着将根据行中的内容来调整行的大小。 默认 Height 为 Star 大小调整,这意味着行将为可用空间的加权比例。 例如,如果两个行的高度均为“*”,则它们各自的高度将为可用空间的一半。
Grid 现在应类似于以下 XAML:
<Grid Margin="10,0,10,10"> <Grid.ColumnDefinitions> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> </Grid>
在本节中,主页 UI 将更新以显示一个人员列表,用户可从中进行选择来查看所选人员的零用金报销单。 控件是一些 UI 对象,这些对象允许用户与应用程序交互。 有关更多信息,请参见控件。
为了创建此 UI,会将以下元素添加到 ExpenseItHome.xaml 中:
将通过设置 Grid.Row 附加属性将每个控件放在 Grid 的一个行中。 有关附加属性的更多信息,请参见附加属性概述。
打开 ExpenseItHome.xaml。
在 Grid 标记之间添加以下 XAML。
<!-- People list --> <Border Grid.Column="0" Grid.Row="0" Height="35" Padding="5" Background="#4E87D4"> <Label VerticalAlignment="Center" Foreground="White">Names</Label> </Border> <ListBox Name="peopleListBox" Grid.Column="0" Grid.Row="1"> <ListBoxItem>Mike</ListBoxItem> <ListBoxItem>Lisa</ListBoxItem> <ListBoxItem>John</ListBoxItem> <ListBoxItem>Mary</ListBoxItem> </ListBox> <!-- View report button --> <Button Grid.Column="0" Grid.Row="2" Margin="0,10,0,0" Width="125" Height="25" HorizontalAlignment="Right">View</Button>
生成并运行应用程序。
下图显示了在本节中通过 XAML 创建的控件。
在本节中,主页 UI 将更新为包含图像和页标题。
打开 ExpenseItHome.xaml。
向 ColumnDefinitions 中添加固定 Width 为 230 像素的另一列。
<Grid.ColumnDefinitions> <ColumnDefinition Width="230" /> <ColumnDefinition /> </Grid.ColumnDefinitions>
向 RowDefinitions 中添加另一行。
<Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions>
通过将 Grid.Column 设置为 1,将控件移到第二列。 通过将 Grid.Row 增加 1,将每个控件下移一行。
<Border Grid.Column="1" Grid.Row="1" Height="35" Padding="5" Background="#4E87D4"> <Label VerticalAlignment="Center" Foreground="White">Names</Label> </Border> <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2"> <ListBoxItem>Mike</ListBoxItem> <ListBoxItem>Lisa</ListBoxItem> <ListBoxItem>John</ListBoxItem> <ListBoxItem>Mary</ListBoxItem> </ListBox> <!-- View report button --> <Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125" Height="25" HorizontalAlignment="Right">View</Button>
将 Grid 的 Background 设置为 watermark.png 图像文件。
<Grid.Background> <ImageBrush ImageSource="watermark.png"/> </Grid.Background>
在 Border 之前,添加一个 Label,其中包含要作为页标题的内容“View Expense Report”(查看零用金报销单)。
<Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" FontWeight="Bold" FontSize="18" Foreground="#0066cc"> View Expense Report </Label>
生成并运行应用程序。
下图显示本节的结果。
打开 ExpenseItHome.xaml。
将 Click 事件处理程序添加到 Button 元素中。 有关更多信息,请参见如何:创建简单的事件处理程序。
<!-- View report button --> <Button Grid.Column="1" Grid.Row="3" Margin="0,10,0,0" Width="125" Height="25" HorizontalAlignment="Right" Click="Button_Click">View</Button>
打开 ExpenseItHome.xaml.vb 或 ExpenseItHome.xaml.cs。
向 Click 事件处理程序中添加以下代码,这些代码使窗口导航到 ExpenseReportPage.xaml 文件。
private void Button_Click(object sender, RoutedEventArgs e) { // View Expense Report ExpenseReportPage expenseReportPage = new ExpenseReportPage(); this.NavigationService.Navigate(expenseReportPage); }
ExpenseReportPage.xaml 显示在 ExpenseItHome.xaml 上所选人员的零用金报销单。 本节为 ExpenseReportPage.xaml 添加控件和创建 UI。 本节还为各种 UI 元素添加背景色和填充颜色。
打开 ExpenseReportPage.xaml。
在 Grid 标记之间添加以下 XAML。
此 UI 类似于在 ExpenseItHome.xaml 上创建的 UI,只不过报告数据显示在 DataGrid 中。
<Grid.Background> <ImageBrush ImageSource="watermark.png" /> </Grid.Background> <Grid.ColumnDefinitions> <ColumnDefinition Width="230" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" FontWeight="Bold" FontSize="18" Foreground="#0066cc"> Expense Report For: </Label> <Grid Margin="10" Grid.Column="1" Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <!-- Name --> <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal"> <Label Margin="0,0,0,5" FontWeight="Bold">Name:</Label> <Label Margin="0,0,0,5" FontWeight="Bold"></Label> </StackPanel> <!-- Department --> <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal"> <Label Margin="0,0,0,5" FontWeight="Bold">Department:</Label> <Label Margin="0,0,0,5" FontWeight="Bold"></Label> </StackPanel> <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Left"> <!-- Expense type and Amount table --> <DataGrid AutoGenerateColumns="False" RowHeaderWidth="0" > <DataGrid.ColumnHeaderStyle> <Style TargetType="{x:Type DataGridColumnHeader}"> <Setter Property="Height" Value="35" /> <Setter Property="Padding" Value="5" /> <Setter Property="Background" Value="#4E87D4" /> <Setter Property="Foreground" Value="White" /> </Style> </DataGrid.ColumnHeaderStyle> <DataGrid.Columns> <DataGridTextColumn Header="ExpenseType" /> <DataGridTextColumn Header="Amount" /> </DataGrid.Columns> </DataGrid> </Grid> </Grid>
生成并运行应用程序。
注意 如果收到指示 DataGrid 未找到或不存在的错误,请确保项目以 .NET Framework 4 为目标。 有关更多信息,请参见如何:面向特定的 .NET Framework 版本或配置文件。
单击“View”(查看)按钮。
零用金报销单页即会出现。
下图显示添加到 ExpenseReportPage.xaml 中的 UI 元素。 请注意,向后导航按钮已启用。
通常情况下,UI 中所有同类型元素的外观可以保持一致。 UI 通过样式使外观可以重用于多个元素。 样式的可重用性有助于简化 XAML 的创建和管理。 有关样式的更多信息,请参见样式设置和模板化。 本节将前面的步骤中定义的各元素的特性替换为样式。
打开 Application.xaml 或 App.xaml。
在 Application.Resources 标记之间添加以下 XAML:
<!-- Header text style --> <Style x:Key="headerTextStyle"> <Setter Property="Label.VerticalAlignment" Value="Center"></Setter> <Setter Property="Label.FontFamily" Value="Trebuchet MS"></Setter> <Setter Property="Label.FontWeight" Value="Bold"></Setter> <Setter Property="Label.FontSize" Value="18"></Setter> <Setter Property="Label.Foreground" Value="#0066cc"></Setter> </Style> <!-- Label style --> <Style x:Key="labelStyle" TargetType="{x:Type Label}"> <Setter Property="VerticalAlignment" Value="Top" /> <Setter Property="HorizontalAlignment" Value="Left" /> <Setter Property="FontWeight" Value="Bold" /> <Setter Property="Margin" Value="0,0,0,5" /> </Style> <!-- DataGrid header style --> <Style x:Key="columnHeaderStyle" TargetType="{x:Type DataGridColumnHeader}"> <Setter Property="Height" Value="35" /> <Setter Property="Padding" Value="5" /> <Setter Property="Background" Value="#4E87D4" /> <Setter Property="Foreground" Value="White" /> </Style> <!-- List header style --> <Style x:Key="listHeaderStyle" TargetType="{x:Type Border}"> <Setter Property="Height" Value="35" /> <Setter Property="Padding" Value="5" /> <Setter Property="Background" Value="#4E87D4" /> </Style> <!-- List header text style --> <Style x:Key="listHeaderTextStyle" TargetType="{x:Type Label}"> <Setter Property="Foreground" Value="White" /> <Setter Property="VerticalAlignment" Value="Center" /> <Setter Property="HorizontalAlignment" Value="Left" /> </Style> <!-- Button style --> <Style x:Key="buttonStyle" TargetType="{x:Type Button}"> <Setter Property="Width" Value="125" /> <Setter Property="Height" Value="25" /> <Setter Property="Margin" Value="0,10,0,0" /> <Setter Property="HorizontalAlignment" Value="Right" /> </Style>
此 XAML 添加以下样式:
headerTextStyle:设置页标题 Label 的格式。
labelStyle:设置 Label 控件的格式。
columnHeaderStyle:要进行格式设置的 DataGridColumnHeader。
listHeaderStyle:设置列表标题 Border 控件的格式。
listHeaderTextStyle:设置列表标题 Label 的格式。
buttonStyle:设置 ExpenseItHome.xaml 上 Button 的格式。
请注意,样式是 Application.Resources 属性元素的资源和子级。 这里,样式将应用于应用程序中的所有元素。 有关如何在 .NET Framework 应用程序中使用资源的示例,请参见如何:使用应用程序资源。
打开 ExpenseItHome.xaml。
将 Grid 元素之间的所有内容替换为以下 XAML。
<Grid.Background> <ImageBrush ImageSource="watermark.png" /> </Grid.Background> <Grid.ColumnDefinitions> <ColumnDefinition Width="230" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition Height="Auto"/> <RowDefinition /> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <!-- People list --> <Label Grid.Column="1" Style="{StaticResource headerTextStyle}" > View Expense Report </Label> <Border Grid.Column="1" Grid.Row="1" Style="{StaticResource listHeaderStyle}"> <Label Style="{StaticResource listHeaderTextStyle}">Names</Label> </Border> <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2"> <ListBoxItem>Mike</ListBoxItem> <ListBoxItem>Lisa</ListBoxItem> <ListBoxItem>John</ListBoxItem> <ListBoxItem>Mary</ListBoxItem> </ListBox> <!-- View report button --> <Button Grid.Column="1" Grid.Row="3" Click="Button_Click" Style="{StaticResource buttonStyle}">View</Button>
通过应用样式,将移除和替换定义每个控件的外观的属性,例如 VerticalAlignment 和 FontFamily。 例如,将 headerTextStyle 应用于“View Expense Report”(查看零用金报销单)Label。
打开 ExpenseReportPage.xaml。
将 Grid 元素之间的所有内容替换为以下 XAML。
<Grid.Background> <ImageBrush ImageSource="watermark.png" /> </Grid.Background> <Grid.ColumnDefinitions> <ColumnDefinition Width="230" /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <Label Grid.Column="1" Style="{StaticResource headerTextStyle}"> Expense Report For: </Label> <Grid Margin="10" Grid.Column="1" Grid.Row="1"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <!-- Name --> <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal"> <Label Style="{StaticResource labelStyle}">Name:</Label> <Label Style="{StaticResource labelStyle}"></Label> </StackPanel> <!-- Department --> <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal"> <Label Style="{StaticResource labelStyle}">Department:</Label> <Label Style="{StaticResource labelStyle}"></Label> </StackPanel> <Grid Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="2" VerticalAlignment="Top" HorizontalAlignment="Left"> <!-- Expense type and Amount table --> <DataGrid ColumnHeaderStyle="{StaticResource columnHeaderStyle}" AutoGenerateColumns="False" RowHeaderWidth="0" > <DataGrid.Columns> <DataGridTextColumn Header="ExpenseType" /> <DataGridTextColumn Header="Amount" /> </DataGrid.Columns> </DataGrid> </Grid> </Grid>
生成并运行应用程序。
在本节中添加 XAML 之后,应用程序看上去与使用样式更新之前一样。
在本节中,将创建绑定到各种控件的 XML 数据。
打开 ExpenseItHome.xaml。
在起始 Grid 元素中,添加以下 XAML,以创建包含每个人员的数据的 XmlDataProvider。
将以 Grid 资源的形式创建数据。 通常,此数据将以文件形式加载,但为了简单起见,将以内联方式添加数据。
<Grid.Resources> ... <!-- Expense Report Data --> <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses"> <x:XData> <Expenses xmlns=""> <Person Name="Mike" Department="Legal"> <Expense ExpenseType="Lunch" ExpenseAmount="50" /> <Expense ExpenseType="Transportation" ExpenseAmount="50" /> </Person> <Person Name="Lisa" Department="Marketing"> <Expense ExpenseType="Document printing" ExpenseAmount="50"/> <Expense ExpenseType="Gift" ExpenseAmount="125" /> </Person> <Person Name="John" Department="Engineering"> <Expense ExpenseType="Magazine subscription" ExpenseAmount="50"/> <Expense ExpenseType="New machine" ExpenseAmount="600" /> <Expense ExpenseType="Software" ExpenseAmount="500" /> </Person> <Person Name="Mary" Department="Finance"> <Expense ExpenseType="Dinner" ExpenseAmount="100" /> </Person> </Expenses> </x:XData> </XmlDataProvider> ... </Grid.Resources>
在 Grid 资源中,添加以下 DataTemplate,它定义如何在 ListBox 中显示数据。 有关数据模板的更多信息,请参见数据模板化概述。
<Grid.Resources> ... <!-- Name item template --> <DataTemplate x:Key="nameItemTemplate"> <Label Content="{Binding XPath=@Name}"/> </DataTemplate> ... </Grid.Resources>
将现有 ListBox 替换为以下 XAML。
<ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}" ItemTemplate="{StaticResource nameItemTemplate}"> </ListBox>
此 XAML 将 ListBox 的 ItemsSource 属性绑定到数据源,并应用数据模板作为 ItemTemplate。
在本节中,您将编写代码来检索在 ExpenseItHome.xaml 页上的人员列表中选定的当前项,并在实例化过程中将对该当前项的引用传递给ExpenseReportPage 的构造函数。 ExpenseReportPage 使用已传入的项设置数据上下文,这就是 ExpenseReportPage.xaml 中定义的控件要绑定的内容。
打开 ExpenseReportPage.xaml.vb 或 ExpenseReportPage.xaml.cs。
添加一个构造函数,该函数获取一个对象,以便您能够传递所选人员的零用金报销单数据。
public partial class ExpenseReportPage : Page { public ExpenseReportPage() { InitializeComponent(); } // Custom constructor to pass expense report data public ExpenseReportPage(object data):this() { // Bind to expense report data. this.DataContext = data; } }
打开 ExpenseItHome.xaml.vb 或 ExpenseItHome.xaml.cs。
更改 Click 事件处理程序,以调用传递所选人员的零用金报销单数据的新构造函数。
private void Button_Click(object sender, RoutedEventArgs e) { // View Expense Report ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem); this.NavigationService.Navigate(expenseReportPage); }
在本节中,您将使用数据模板来更新数据绑定列表中各项的 UI。
打开 ExpenseReportPage.xaml。
将“Name”(名称)和“Department”(部门)Label元素的内容绑定到相应的数据源属性。 有关数据绑定的更多信息,请参见 数据绑定概述。
<!-- Name --> <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="0" Orientation="Horizontal"> <Label Style="{StaticResource labelStyle}">Name:</Label> <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Name}"></Label> </StackPanel> <!-- Department --> <StackPanel Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" Orientation="Horizontal"> <Label Style="{StaticResource labelStyle}">Department:</Label> <Label Style="{StaticResource labelStyle}" Content="{Binding XPath=@Department}"></Label> </StackPanel>
打开 Grid 元素后,添加以下数据模板,这些数据模板定义如何显示零用金报销单数据。
<!--Templates to display expense report data--> <Grid.Resources> <!-- Reason item template --> <DataTemplate x:Key="typeItemTemplate"> <Label Content="{Binding XPath=@ExpenseType}"/> </DataTemplate> <!-- Amount item template --> <DataTemplate x:Key="amountItemTemplate"> <Label Content="{Binding XPath=@ExpenseAmount}"/> </DataTemplate> </Grid.Resources>
将模板应用于显示零用金报销单数据的 DataGrid 列。
<!-- Expense type and Amount table --> <DataGrid ItemsSource="{Binding XPath=Expense}" ColumnHeaderStyle="{StaticResource columnHeaderStyle}" AutoGenerateColumns="False" RowHeaderWidth="0" > <DataGrid.Columns> <DataGridTextColumn Header="ExpenseType" Binding="{Binding XPath=@ExpenseType}" /> <DataGridTextColumn Header="Amount" Binding="{Binding XPath=@ExpenseAmount}" /> </DataGrid.Columns> </DataGrid>
生成并运行应用程序。
选择一个人员,并单击“View”(查看)按钮。
下图显示应用了控件、布局、样式、数据绑定和数据模板的 ExpenseIt 应用程序的两个页。