Пошаговое руководство. Начало работы с WPF

В этом пошаговом руководстве представлены общие сведения о разработке приложений 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#; см. раздел Введение в разработку приложений WPF.

Предварительные требования

Ниже приведены компоненты, необходимые для выполнения данного пошагового руководства.

  • Visual Studio 2010

Дополнительные сведения об установке Visual Studio см. в разделе Установка Visual Studio.

Создание проекта приложения

В этом разделе создается инфраструктура приложения, включающая определение приложения, две страницы и изображение.

  1. Создайте новый проект приложения WPF на языке Visual Basic или Visual C# с именем ExpenseIt. Дополнительные сведения см. в разделе Практическое руководство. Создание нового проекта приложения WPF.

    ПримечаниеПримечание

    В этом пошаговом руководстве используется элемент управления 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:

    <Application x:Class="Application"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        StartupUri="MainWindow.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    

    А в C# он должен выглядеть следующим образом:

    <Application x:Class="ExpenseIt.App"
         xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
         StartupUri="MainWindow.xaml">
        <Application.Resources>
    
        </Application.Resources>
    </Application>
    
  3. Откройте файл MainWindow.xaml.

    Этот XAML-файл представляет главное окно приложения, в котором отображается созданное содержимое страниц. Класс Window определяет свойства окна, такие как заголовок, размер и значок, и обрабатывает события, такие как открытие и закрытие окна.

  4. Замените элемент Window на NavigationWindow.

    Приложение будет переходить к различному содержимому согласно действиям пользователя. Поэтому главное окно Window необходимо изменить на NavigationWindow. Класс NavigationWindow наследует все свойства класса Window. Элемент NavigationWindow в XAML-файле создает экземпляр класса NavigationWindow. Дополнительные сведения см. в разделе Общие сведения о переходах.

  5. Измените следующие свойства элемента NavigationWindow.

    • Задайте свойству Title значение "ExpenseIt".

    • Задайте свойству Width значение 500 пикселей.

    • Задайте свойству Height значение 350 пикселей.

    • Удалите элементы Grid между тегами NavigationWindow.

    XAML-код должен выглядеть следующим образом в Visual Basic:

    <NavigationWindow x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
    
    </NavigationWindow>
    

    А в C# он должен выглядеть следующим образом:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500">
    
    </NavigationWindow>
    
  6. Откройте файл MainWindow.xaml.vb или MainWindow.xaml.cs.

    В этом файле кода программной части содержится код обработки событий, объявленных в файле MainWindow.xaml. В этом файле содержится разделяемый класс окна, определенного в XAML-коде.

  7. Если используется язык C#, измените класс MainWindow так, чтобы он наследовался от класса NavigationWindow.

    В языке Visual Basic это выполняется автоматически при изменении окна в XAML-коде.

    Код должен выглядеть следующим образом.

    Class MainWindow
    
    End Class
    
    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();
            }
        }
    }
    

Добавление файлов в приложение

В этом разделе в приложение добавляются две страницы и изображение.

  1. Добавьте в проект новую страницу (WPF) с именем ExpenseItHome.xaml. Дополнительные сведения см. в разделе Практическое руководство. Добавление новых элементов в проекте WPF.

    Эта страница отображается первой при запуске приложения. На ней выводится список, в котором можно выбрать человека и просмотреть отчет о его затратах.

  2. Откройте файл ExpenseItHome.xaml.

  3. Задайте свойству Title значение "ExpenseIt - Home".

    XAML-код должен выглядеть следующим образом в Visual Basic:

    <Page x:Class="ExpenseItHome"
      xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="https://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="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://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:

    <NavigationWindow x:Class="MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    
    </NavigationWindow>
    

    А в C# он должен выглядеть следующим образом:

    <NavigationWindow x:Class="ExpenseIt.MainWindow"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        Title="ExpenseIt" Height="350" Width="500" Source="ExpenseItHome.xaml">
    
    </NavigationWindow>
    
  6. Добавьте в проект новую страницу (WPF) с именем ExpenseReportPage.xaml.

    На этой странице будет представлен отчет о расходах для человека, выбранного на странице ExpenseItHome.xaml.

  7. Откройте файл ExpenseReportPage.xaml.

  8. Задайте свойству Title значение "ExpenseIt - View Expense".

    XAML-код должен выглядеть следующим образом в Visual Basic:

    <Page x:Class="ExpenseReportPage"
          xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://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="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:mc="https://schemas.openxmlformats.org/markup-compatibility/2006" 
          xmlns:d="https://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.vb и ExpenseReportPage.xaml.vb (или ExpenseItHome.xaml.cs и ExpenseReportPage.xaml.cs).

    При создании нового файла страницы Visual Studio автоматически создает файл кода программной части. Эти файлы кода программной части обрабатывают логику, реагирующую на действия пользователя.

    Код должен выглядеть следующим образом.

    Class ExpenseItHome
    
    End Class
    
    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();
            }
        }
    }
    
    Class ExpenseReportPage
    
    End Class
    
    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. Выполните построение и запуск приложения, воспользовавшись клавишей F5 или выбрав пункт Начать отладку в меню Отладка.

    На следующем рисунке показано приложение с кнопками окна NavigationWindow.

    Снимок экрана примера ExpenseIt

  2. Закройте приложение и вернитесь в Visual Studio.

Создание макета

Макет обеспечивает упорядоченное расположение элементов UI, а также управление их размером и положением при изменении размера UI. Обычно макет создается с одним из следующих элементов управления макетом:

Для каждого из этих элементов управления макетом поддерживается специальный тип макета дочерних элементов. Размер страниц приложения ExpenseIt может быть изменен. На каждой странице представлены элементы, которые упорядочены по горизонтали и вертикали рядом с другими элементами. Следовательно, Grid является идеальным элементом макета для приложения.

ПримечаниеПримечание

Дополнительные сведения об элементах Panel см. в разделе Общие сведения о панелях.Дополнительные сведения о макете см. в разделе Система макета.

В этом разделе создается таблица с одним столбцом, тремя строками и полями шириной 10 пикселей путем добавления определений столбцов и строк в класс Grid в файле ExpenseItHome.xaml.

  1. Откройте файл ExpenseItHome.xaml.

  2. Задайте свойству Margin элемента Grid значение "10,0,10,10", указывающее ширину полей слева, сверху, справа и снизу соответственно.

  3. Добавьте следующий XAML-код между тегами Grid, чтобы создать определения строк и столбцов. 

    <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, в файл ExpenseItHome.xaml необходимо добавить следующие элементы.

  • ListBox — отображение списка людей.

  • Label — заголовок списка.

  • Button — кнопка для просмотра отчета о расходах для выбранного в списке человека.

Каждый элемент управления необходимо поместить в строку таблицы Grid, указав вложенное свойство Grid.Row. Дополнительные сведения о вложенных свойствах см. в разделе Общие сведения о вложенных свойствах зависимостей.

  1. Откройте файл ExpenseItHome.xaml.

  2. Добавьте следующий XAML-код между тегами Grid.

    
      <!-- 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. Постройте и запустите приложение.

На следующем рисунке показаны элементы управления, созданные с помощью XAML-кода в этом разделе.

Снимок экрана примера ExpenseIt

Добавление изображения и заголовка

В этом разделе обновляется UI домашней страницы: на нее добавляется изображение и заголовок страницы.

  1. Откройте файл ExpenseItHome.xaml.

  2. Добавьте столбец в свойство ColumnDefinitions с фиксированной длиной Width 230 пикселей.

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
  3. Добавьте строку в свойство RowDefinitions.

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
  4. Переместите элементы управления во второй столбец, задав свойству 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>
    
  5. В качестве значения свойства Background класса Grid задайте файл изображения watermark.png.

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"/>
    </Grid.Background>
    
  6. В заголовке страницы перед элементом Border добавьте элемент Label с содержимым "View Expense Report".

    <Label Grid.Column="1" VerticalAlignment="Center" FontFamily="Trebuchet MS" 
            FontWeight="Bold" FontSize="18" Foreground="#0066cc">
        View Expense Report
    </Label>
    
  7. Постройте и запустите приложение.

На следующем рисунке показаны результаты действий из этого раздела.

Снимок экрана примера ExpenseIt

Добавление кода для обработки событий

  1. Откройте файл ExpenseItHome.xaml.

  2. Добавьте обработчик событий 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>
    
  3. Откройте файл ExpenseItHome.xaml.vb или ExpenseItHome.xaml.cs.

  4. Добавьте в обработчик событий Click следующий код, обеспечивающий переход окна к файлу ExpenseReportPage.xaml.

            Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                ' View Expense Report
                Dim expenseReportPage As New ExpenseReportPage()
                Me.NavigationService.Navigate(expenseReportPage)
    
            End Sub
    
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage();
        this.NavigationService.Navigate(expenseReportPage);
    
    }
    

Создание пользовательского интерфейса для страницы ExpenseReportPage

На странице ExpenseReportPage.xaml отображается отчет о расходах для человека, выбранного на странице ExpenseItHome.xaml. В этом разделе на страницу ExpenseReportPage.xaml добавляются элементы управления, и для нее создается UI. На нее также добавляется фон и цвета заливки для различных элементов UI.

  1. Откройте файл ExpenseReportPage.xaml.

  2. Добавьте следующий XAML-код между тегами Grid.

    Этот пользовательский интерфейс аналогичен пользовательскому интерфейсу, созданному в файле ExpenseItHome.xaml, за исключением того, что данные отчета отображаются в элементе управления 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>
    
  3. Постройте и запустите приложение.

    ПримечаниеПримечание

    При появлении сообщения об ошибке, указывающего, что элемент управления DataGrid не найден или не существует, убедитесь, что проект предназначен для платформы .NET Framework 4.Дополнительные сведения см. в разделе Практическое руководство. Указание конкретной версии или профиля платформы .NET Framework.

  4. Нажмите кнопку View (Просмотреть).

    Отобразится отчет о затратах.

На следующем рисунке показаны элементы UI, добавленные на страницу ExpenseReportPage.xaml. Обратите внимание, что доступна кнопка "назад".

Снимок экрана примера ExpenseIt

Цвета стилей

UI часто подразумевает одинаковый внешний вид различных элементов для всех элементов одного типа. UI использует стили, чтобы варианты внешнего вида можно было многократно использовать для нескольких элементов. Повторное использование стилей помогает упростить создание XAML-кода и управление им. За дополнительными сведениями о стилях обратитесь к разделу Стилизация и использование шаблонов. В этом разделе атрибуты, установленные ранее для каждого элемента, заменяются стилями.

  1. Откройте файл Application.xaml или App.xaml.

  2. Добавьте следующий XAML-код между тегами Application.Resources.

    
    <!-- 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 — форматирование элемента Button в файле ExpenseItHome.xaml.

    Обратите внимание, что стили представляют собой ресурсы и являются дочерними элементами свойства Application.Resources. Здесь стили применяются ко всем элементам в приложении. Пример использования ресурсов в приложении .NET Framework см. в разделе Практическое руководство. Использование ресурсов приложения.

  3. Откройте файл ExpenseItHome.xaml.

  4. Замените все содержимое между элементами 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).

  5. Откройте файл ExpenseReportPage.xaml.

  6. Замените все содержимое между элементами 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>
    

    Таким образом, в элементы Label и Border будут добавлены стили.

  7. Постройте и запустите приложение.

    После добавления XAML-кода в этом разделе приложение выглядит так же, как и перед обновлением с использованием стилей.

Привязка данных к элементу управления

В этом разделе создаются XML-данные, привязанные к различным элементам управления.

  1. Откройте файл ExpenseItHome.xaml.

  2. Открыв элемент Grid, добавьте следующий XAML-код для создания объекта XmlDataProvider, содержащего данные по каждому человеку.

    Данные создаются в качестве ресурса объекта Grid. Обычно такие ресурсы загружаются в виде файла, но в данном случае данные добавлены в код для простоты.

    <Grid.Resources>
    
    
    ...
    
    
    <!-- Expense Report Data -->
    <XmlDataProvider x:Key="ExpenseDataSource" XPath="Expenses">
        <x:XData>
            <Expenses >
                <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>
    
  3. В ресурсе Grid добавьте следующий элемент DataTemplate, определяющий способ отображения данных в списке ListBox. Дополнительные сведения о шаблонах данных см. в разделе Общие сведения о шаблонах данных.

    <Grid.Resources>
    
    
    ...
    
    
    <!-- Name item template -->
    <DataTemplate x:Key="nameItemTemplate">
        <Label Content="{Binding XPath=@Name}"/>
    </DataTemplate>
    
    
    ...
    
    
    </Grid.Resources>
    
  4. Замените существующий класс ListBox следующим 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.xaml, и передающий его ссылку конструктору элемента ExpenseReportPage во время создания объекта. ExpenseReportPage задает контекст данных для переданного элемента, к которому будут привязаны элементы управления, определенные в файле ExpenseReportPage.xaml.

  1. Откройте файл ExpenseReportPage.xaml.vb или ExpenseReportPage.xaml.cs.

  2. Добавьте конструктор, принимающий объект, чтобы можно было передать данные отчета о затратах выбранного человека.

        Partial Public Class ExpenseReportPage
            Inherits Page
            Public Sub New()
                InitializeComponent()
            End Sub
    
            ' Custom constructor to pass expense report data
            Public Sub New(ByVal data As Object)
                Me.New()
                ' Bind to expense report data.
                Me.DataContext = data
            End Sub
    
        End Class
    
    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 так, чтобы он вызывал новый конструктор и передавал ему данные отчета о затратах выбранного человека.

            Private Sub Button_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
                ' View Expense Report
                Dim expenseReportPage As New ExpenseReportPage(Me.peopleListBox.SelectedItem)
                Me.NavigationService.Navigate(expenseReportPage)
    
            End Sub
    
    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. Привяжите содержимое "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>
    
  3. После открывающего элемента 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>
    
  4. Примените шаблоны к столбцам 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>
    
  5. Постройте и запустите приложение.

  6. Выберите человека и нажмите кнопку View (Просмотреть).

На следующем рисунке представлены обе страницы приложения ExpenseIt, к которым применены элементы управления, макет, стили, привязка данных и шаблоны данных.

Снимки экрана примера ExpenseIt

Рекомендации

В этом примере демонстрируется конкретная функциональная возможность WPF, поэтому рекомендации по разработке приложений не соблюдаются. Подробные рекомендации по разработке приложений для WPF и .NET Framework см. в следующих разделах.

Что дальше?

Теперь вы ознакомились с различными способами создания UI с использованием Windows Presentation Foundation (WPF). Далее следует более основательно изучить основные конструктивные блоки приложений .NET Framework с привязкой к данным. Целью этого раздела не являлось углубленное изучение, однако вы получили общие сведения, которые могут использоваться в качестве базы для самостоятельного изучения возможностей, не освещенных в этом разделе.

Дополнительные сведения об архитектуре и моделях программирования WPF см. в следующих разделах.

Подробные сведения о создании приложений см. в следующих разделах.

См. также

Основные понятия

Общие сведения о панелях

Общие сведения о шаблонах данных

Построение приложения WPF

Другие ресурсы

Стили и шаблоны

Журнал изменений

Дата

Журнал

Причина

Декабрь 2010

Добавлены примечания о необходимости настройки на платформу .NET Framework 4.

Улучшение информации.