XAML入门课程-我的第一个 WPF 桌面应用程序

这篇文章演示如何开发简单的 Windows Presentation Foundation (WPF) 应用程序包括元素所共有的大多数 WPF 应用程序: 可扩展应用程序标记语言 (XAML) 标记、 代码隐藏、 应用程序定义控件、 布局、 数据绑定和样式。

本演练包含以下步骤:

  • 使用 XAML 设计应用程序的用户界面 (UI) 的外观。

  • 编写代码以生成应用程序的行为。

  • 创建应用程序定义管理应用程序。

  • 添加控件并创建布局以构成应用程序 UI。

  • 创建在应用程序的 UI 整个一致的外观样式。

  • 绑定到数据填充数据从用户界面的同时保护数据和 UI 同步的用户界面。

本演练结束时,您将构建的独立 Windows 应用程序,用户可查看所选人员的费用报销。 该应用程序由多个浏览器样式窗口中承载的 WPF 页面。

提示

用于生成本演练的示例代码是适用于 Visual Basic 和 C# 在生成 WPF 应用程序简介

系统必备

  • Visual Studio 2012 或更高版本

有关安装最新版本的 Visual Studio 的详细信息,请参阅安装 Visual Studio

创建应用程序项目

第一步是创建应用程序基础结构,其中包括应用程序定义、 两个页面和映像。

  1. 创建新的 WPF 应用程序项目中 Visual Basic 或 Visual C# 名为ExpenseIt:

    1. 打开 Visual Studio 并选择文件 > 新建 > 项目

      新项目对话框随即打开。

    2. 已安装类别中,展开Visual C# 或Visual Basic节点,,然后选择Windows 经典桌面

    3. 选择WPF 应用程序 (.NET Framework) 模板。 输入的名称ExpenseIt ,然后选择确定

      与选择的 WPF 应用程序的新建项目对话框

      Visual Studio 创建项目并打开名为的默认应用程序窗口的设计器MainWindow.xaml

    备注

    本演练使用DataGrid可用在.NET Framework 4 和更高版本的控件。 为确保你的项目面向.NET Framework 4 或更高版本。 有关详细信息,请参阅如何:面向 .NET Framework 的某个版本

  2. 打开Application.xaml (Visual Basic) 或App.xaml (C#)。

    此 XAML 文件定义一个 WPF 应用程序和任何应用程序资源。 此外使用此文件来指定何时将自动显示 UI 应用程序启动;在这种情况下, MainWindow.xaml

    在 XAML 应如下所示在 Visual Basic 中:

    XAML复制
    <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# 中是这样:

    XAML复制
    <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>
    
  3. 打开MainWindow.xaml

    此 XAML 文件是你的应用程序的主窗口,并显示在页中创建的内容。 Window类定义的属性窗口中,例如,其标题、 大小或图标,并处理事件,例如关闭或隐藏。

  4. 更改Window元素NavigationWindow,下面的 XAML 中所示:

    XAML复制
    <NavigationWindow x:Class="ExpenseIt.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         ...
    </NavigationWindow>
    

    此应用导航到不同的内容,具体取决于用户输入。 正因如此主Window需要更改为NavigationWindow NavigationWindow 继承的所有属性Window NavigationWindow XAML 文件中的元素创建的实例NavigationWindow类。 有关详细信息,请参阅导航概述

  5. 在更改下列属性NavigationWindow元素:

    在 XAML 应如下所示在 Visual Basic 中:

    XAML复制
    <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# 中是这样:

    XAML复制
    <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>
    
  6. 打开MainWindow.xaml.vbMainWindow.xaml.cs

    此文件是包含代码来处理中声明的事件的代码隐藏文件MainWindow.xaml 此文件包含在 XAML 中定义的窗口的分部类。

  7. 如果你使用的 C#,更改MainWindow类以派生自NavigationWindow (在 Visual Basic 中,自动发生此情况时更改 XAML 中的窗口。)

    你的代码应如下所示:

    C#复制
    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();
            }
        }
    }
    

    提示

    您可以切换之间 C# 和 Visual Basic 中的示例代码的代码语言语言这篇文章右上方的下拉列表。

将文件添加到应用程序

本部分将向应用程序添加两个页面和一个图像。

  1. 将新的 WPF 页添加到项目中,并将其命名ExpenseItHome.xaml:

    1. 解决方案资源管理器,右键单击ExpenseIt项目节点,选择添加 > 

    2. 添加新项对话框中,页 (WPF) 尚未选择模板。 输入的名称ExpenseItHome,然后选择添加

    此页是启动应用程序时显示的第一页。 它将显示要选择,从显示的支出报表的人员列表。

  2. 打开 ExpenseItHome.xaml

  3. 设置Title到"ExpenseIt-主页"。

    在 XAML 应如下所示在 Visual Basic 中:

    XAML复制
    <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# 中是这样:

    XAML复制
    <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>
    
  4. 打开MainWindow.xaml

  5. 设置Source属性NavigationWindow到"ExpenseItHome.xaml"。

    这将 ExpenseItHome.xaml 设置为应用程序启动时第一个打开的页。 在 XAML 应如下所示在 Visual Basic 中:

    XAML复制
    <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# 中是这样:

    XAML复制
    <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>
    

    提示

    你还可以设置中的属性杂项类别属性窗口。

    在属性窗口中的源属性

  6. 将另一个新的 WPF 页添加到项目中,并将其命名ExpenseReportPage.xaml::

    1. 解决方案资源管理器,右键单击ExpenseIt项目节点,选择添加 > 

    2. 添加新项对话框中,页 (WPF) 尚未选择模板。 输入的名称ExpenseReportPage,然后选择添加

    此页会显示费用报表上所选的人员ExpenseItHome页。

  7. 打开 ExpenseReportPage.xaml

  8. 设置Title到"ExpenseIt-View Expense"。

    在 XAML 应如下所示在 Visual Basic 中:

    XAML复制
    <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# 中是这样:

    XAML复制
    <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>
    
  9. 打开ExpenseItHome.xaml.vbExpenseReportPage.xaml.vb,或ExpenseItHome.xaml.csExpenseReportPage.xaml.cs.

    当你创建新的页面文件时,Visual Studio 将自动创建代码隐藏文件。 这些代码隐藏文件处理响应用户输入的逻辑。

    你的代码应如下所示为ExpenseItHome:

    C#复制
    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>
        public partial class ExpenseItHome : Page
        {
            public ExpenseItHome()
            {
                InitializeComponent();
            }
        }
    }
    

    和如下有关ExpenseReportPage:

    C#复制
    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>
        public partial class ExpenseReportPage : Page
        {
            public ExpenseReportPage()
            {
                InitializeComponent();
            }
        }
    }
    
  10. 添加了名为映像watermark.png到项目。 您可以创建自己的映像,示例代码中的文件复制或获取它此处

    1. 右键单击项目节点并选择添加 > 现有项,或按Shift+AltA

    2. 添加现有项对话框中,浏览到你想要使用,然后选择映像文件添加

编译和运行应用程序

  1. 若要生成并运行应用程序,请按F5或选择启动调试调试菜单。

    下图显示具有的应用程序NavigationWindow按钮:

    ExpenseIt 示例屏幕快照

  2. 关闭应用程序返回到 Visual Studio。

创建布局

布局提供有序的方式来放置 UI 元素,并还管理的大小和位置,这些元素的 UI 调整大小时。 通常使用以下布局控件之一来创建布局:

每个布局控件都为子元素支持特殊类型的布局。 ExpenseIt 页面可进行调整,并且每个页面均有与其他元素水平或垂直排列的元素。 因此,Grid是应用程序的理想布局元素。

提示

有关详细信息Panel元素,请参阅面板概述 有关布局详细信息,请参阅布局

在部分中,你创建一个单列的表具有三个行和 10 像素边距通过添加到的列和行定义GridExpenseItHome.xaml

  1. 打开 ExpenseItHome.xaml

  2. 设置Margin属性Grid"10,0,10,10",对应于左侧、 顶部、 右侧和底部边距的元素:

    XAML复制
    <Grid Margin="10,0,10,10">
    

    提示

    你还可以设置边距中值属性窗口下布局类别:

    在属性窗口中的边距值

  3. 将以下 XAML 之间添加Grid标记以创建行和列定义:

    XAML复制
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    

    Height的两个行设置为Auto,行大小将调整这意味着根据行中的内容。 默认值HeightStar调整大小,这意味着行高度的可用空间的加权的比例。 例如,如果两个行具有Height的"*",它们每个具有高度的一半的可用空间。

    Grid现在应类似下面的 XAML:

    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:

  • ListBox (有关的人员列表)。
  • Label (对于列表标头)。
  • Button (若要单击以查看费用报表列表中选择的人员)。

每个控件所在的行中Grid通过设置Grid.Row附加属性。 有关附加属性的详细信息,请参阅附加属性概述

  1. 打开 ExpenseItHome.xaml

  2. 添加以下 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>
    

    提示

    你还可以通过将其从拖动创建控件工具箱窗口拖到设计窗口中,然后设置其属性属性窗口。

  3. 生成并运行应用程序。

下图显示了刚创建的控件:

ExpenseIt 示例屏幕快照

添加的映像和标题

在此部分中,你将使用的映像和页面标题更新主页 UI。

  1. 打开 ExpenseItHome.xaml

  2. 添加到另一列ColumnDefinitions带有固定Width为 230 像素:

    XAML复制
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
  3. 添加到另一个行RowDefinitions,四行的总计的:

    XAML复制
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
  4. 将控件移至第二列中,通过设置Grid.Column为 1 每三个控件 (边框、 列表框中和按钮) 中的属性。

  5. 每个控件下移一行时,通过将递增其Grid.Row值加 1。

    这三个控件的 XAML 现在如下所示:

    XAML复制
      <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>
    
  6. 设置BackgroundGridwatermark.png图像文件,请通过添加之间以下某个位置的 XAML<Grid><\/Grid>标记:

    XAML复制
    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"/>
    </Grid.Background>
    
  7. 之前Border元素中,添加Label"查看费用报表"的内容。 这是页的标题。

    XAML复制
    <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
        View Expense Report
    </Label>
    
  8. 生成并运行应用程序。

下图显示您刚添加的结果:

ExpenseIt 示例屏幕快照

添加代码来处理事件

  1. 打开 ExpenseItHome.xaml

  2. 添加Click事件处理程序Button元素。 有关详细信息,请参阅如何: 创建一个简单的事件处理程序

    XAML复制
      <!-- 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>
    
  3. 打开 ExpenseItHome.xaml.vb 或 ExpenseItHome.xaml.cs

  4. 以下代码添加到ExpenseItHome类添加一个按钮单击事件处理程序。 事件处理程序将打开ExpenseReportPage页。

    C#复制
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage();
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

为 ExpenseReportPage 创建 UI

ExpenseReportPage.xaml上所选的人员显示费用报表ExpenseItHome页。 在本部分中,可以将控件和创建用于 UI ExpenseReportPage 你将添加背景,并填充到各种 UI 元素的颜色。

  1. 打开 ExpenseReportPage.xaml

  2. 将以下 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" 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>
    

    此 UI 是类似于ExpenseItHome.xaml,只是报表数据将显示在DataGrid

  3. 生成并运行应用程序。

    备注

    如果收到错误DataGrid找不到或不存在,请确保你的项目面向.NET Framework 4 或更高版本。有关详细信息,请参阅如何:面向 .NET Framework 的某个版本

  4. 选择视图按钮。

    出现费用报告页。 另请注意启用了向后导航按钮。

下图显示添加到 UI 元素ExpenseReportPage.xaml

ExpenseIt 示例屏幕快照

风格的控件

各种元素的外观通常是相同的 UI 中的相同类型的所有元素。 UI 使用样式以使多个元素的外观可重复使用。 可重用性的样式可帮助简化 XAML 创建和管理。 本部分替换在以前步骤中通过样式定义的按元素划分的属性。

  1. 打开Application.xamlApp.xaml

  2. 将以下 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: 若要设置格式ButtonExpenseItHome.xaml 上。

    请注意,样式是资源和子级Application.Resources属性元素。 在此位置中,这些样式将应用到应用程序中的所有元素。 有关在.NET Framework 应用程序中使用资源的示例,请参阅使用应用程序资源

  3. 打开 ExpenseItHome.xaml

  4. 替换之间的所有内容Grid使用以下 XAML 元素:

    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应用于"查看费用报表" Label

  5. 打开 ExpenseReportPage.xaml

  6. 替换之间的所有内容Grid使用以下 XAML 元素:

    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>
    

    这会将样式添加到 Label 和 Border 元素。

将数据绑定到控件

在此部分中,你将创建绑定到各种控件的 XML 数据。

  1. 打开 ExpenseItHome.xaml

  2. 在起始Grid元素中,添加以下 XAML,以创建XmlDataProvider包含每人数据:

    XAML复制
    <Grid.Resources>
    
    XAML复制
    <!-- 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>
    
    XAML复制
    </Grid.Resources>
    

    作为创建数据Grid资源。 这通常会作为文件加载,但为简单起见数据以内联方式添加。

  3. <Grid.Resources>元素中,添加以下DataTemplate,它定义如何显示中的数据ListBox:

    XAML复制
    <Grid.Resources>
    
    XAML复制
    <!-- Name item template -->
    <DataTemplate x:Key="nameItemTemplate">
        <Label Content="{Binding XPath=@Name}"/>
    </DataTemplate>
    
    XAML复制
    </Grid.Resources>
    

    有关数据模板的详细信息,请参阅数据模板化概述

  4. 将现有ListBox使用以下 XAML:

    XAML复制
    <ListBox Name="peopleListBox" Grid.Column="1" Grid.Row="2" 
             ItemsSource="{Binding Source={StaticResource ExpenseDataSource}, XPath=Person}"
             ItemTemplate="{StaticResource nameItemTemplate}">
    </ListBox>
    

    此 XAML 将绑定ItemsSource属性ListBox到数据源并应用数据模板作为ItemTemplate

将数据连接到控件

接下来,将添加代码以检索选择的名称ExpenseItHome页上,并将其传递给构造函数的ExpenseReportPage ExpenseReportPage设置与所传递的项目,这是控件定义其数据上下文中ExpenseReportPage.xaml将绑定到。

  1. 打开 ExpenseReportPage.xaml.vb 或 ExpenseReportPage.xaml.cs

  2. 添加获取对象的构造函数,以便传递所选人员的费用报表数据。

    C#复制
    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;
        }
    
    }
    
  3. 打开 ExpenseItHome.xaml.vb 或 ExpenseItHome.xaml.cs

  4. 更改Click事件处理程序以调用新的构造函数传递所选人员的费用报表数据。

    C#复制
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

使用数据模板的样式数据

在此部分中,你将使用数据模板更新数据绑定列表中每个项的 UI。

  1. 打开 ExpenseReportPage.xaml

  2. 将绑定的内容的"名称"和"部门"Label元素与适当的数据源属性。 有关数据绑定的详细信息,请参阅数据绑定概述

    XAML复制
    <!-- 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>
    
  3. 在起始Grid元素中,添加以下数据模板,定义如何显示费用报表数据:

    XAML复制
    <!--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>
    
  4. 应用到模板DataGrid列显示费用报表数据。

    XAML复制
    <!-- 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>
    
  5. 生成并运行应用程序。

  6. 选择 person,然后选择视图按钮。

下图显示控件、 布局、 样式、 数据绑定和数据模板的 ExpenseIt 应用程序的两个页面:

ExpenseIt 示例屏幕快照

备注

此示例演示了 WPF 的特定功能,并不遵循所有最佳实践安全、 本地化和可访问性之类的内容。 有关 WPF 和.NET Framework 应用程序开发最佳做法的全面介绍,请参阅以下主题:

后续步骤

在本演练中你学习了大量的用于创建使用 Windows Presentation Foundation (WPF) UI 技术。 你应该已经基本了解数据绑定,.NET Framework 应用程序的构建基块。 有关 WPF 体系结构和编程模型的详细信息,请参阅以下主题:

有关创建应用程序的详细信息,请参阅以下主题:

请参阅

猜你喜欢

转载自blog.csdn.net/yelin042/article/details/80700437