Поделиться через


Руководство: Создание первого приложения WPF в Visual Studio 2019

В этой статье показано, как разработать настольное приложение Windows Presentation Foundation (WPF), которое включает элементы, обычно встречающиеся в большинстве приложений WPF: расширяемый язык разметки приложений (XAML), код, отделённый от разметки, определения приложений, элементы управления, макет, привязка данных и стили. Для разработки приложения вы будете использовать Visual Studio.

Важный

Эта статья была написана для .NET Framework. Чтобы начать работу с .NET 7, см. статью Учебник: Создание нового WPF-приложения (WPF .NET).

В этом руководстве описано, как:

  • Создайте проект WPF.
  • Используйте XAML для разработки внешнего вида пользовательского интерфейса приложения.
  • Напишите код для создания поведения приложения.
  • Создайте определение приложения для управления приложением.
  • Добавьте элементы управления и создайте макет для создания пользовательского интерфейса приложения.
  • Создайте стили для согласованного внешнего вида в пользовательском интерфейсе приложения.
  • Свяжите пользовательский интерфейс с данными, чтобы как заполнять его данными, так и поддерживать синхронизацию между данными и интерфейсом.

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

Совет

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

Вы можете переключать язык кода примера кода между C# и Visual Basic с помощью селектора языка в верхней части этой страницы.

Необходимые условия

  • Visual Studio 2019 с установленной рабочей нагрузкой разработки классических приложений .NET.

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

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

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

  1. Создайте проект приложения WPF в Visual Basic или Visual C# с именем ExpenseIt:

    1. Откройте Visual Studio и выберите Создать проект в меню Начало работы.

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

    2. В раскрывающемся списке языка выберите либо C# или Visual Basic .

    3. Выберите шаблон приложения WPF (.NET Framework) , а затем нажмите Далее.

      Создание диалогового окна проекта

      Откроется диалоговое окно "Настройка нового проекта".

    4. Введите имя проекта ExpenseIt и выберите Создать.

      Настройка диалогового окна нового проекта

      Visual Studio создает проект и открывает конструктор для окна приложения по умолчанию с именем MainWindow.xaml.

  2. Откройте Application.xaml (Visual Basic) или App.xaml (C#).

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

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

  4. Измените элемент Window на NavigationWindow, как показано в следующем 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. Удалите элементы Grid между тегами NavigationWindow.

  6. Измените следующие свойства в коде XAML для элемента NavigationWindow:

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

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

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

    Код 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>
    
  7. Откройте MainWindow.xaml.vb или MainWindow.xaml.cs.

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

  8. Если вы используете 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();
            }
        }
    }
    

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

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

  1. Добавьте новую страницу в проект и назовите ее ExpenseItHome.xaml:

    1. В обозревателе решений щелкните правой кнопкой мыши на узле проекта ExpenseIt и выберите Добавить>страницу.

    2. В диалоговом окне Добавление нового элемента уже выбран шаблон страницы (WPF). Введите имя ExpenseItHome, а затем выберите Добавить.

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

  2. Откройте ExpenseItHome.xaml.

  3. Задайте для Title значение "ExpenseIt - Home".

  4. Задайте для DesignHeight значение 350 пикселей, а DesignWidth — 500 пикселей.

    Теперь 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="350" d:DesignWidth="500"
      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="350" d:DesignWidth="500"
        Title="ExpenseIt - Home">
    
        <Grid>
            
        </Grid>
    </Page>
    
  5. Откройте MainWindow.xaml.

  6. Добавьте свойство Source в элемент NavigationWindow и задайте для него значение "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>
    

    Совет

    Вы также можете задать свойство Source в категории Прочее окна Свойства.

    свойство Source в окне свойств

  7. Добавьте в проект еще одну новую страницу WPF и назовите ее ExpenseReportPage.xaml::

    1. В обозревателе решений щелкните правой кнопкой мыши узел проекта ExpenseIt и выберите Добавить страницу>.

    2. В диалоговом окне Добавление нового элемента выберите шаблон страницы (WPF). Введите имя ExpenseReportPage, а затем выберите Добавить.

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

  8. Откройте ExpenseReportPage.xaml.

  9. Задайте для Title значение "ExpenseIt - View Expense".

  10. Задайте для DesignHeight значение 350 пикселей, а DesignWidth — 500 пикселей.

    ExpenseReportPage.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="350" d:DesignWidth="500"
          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="350" d:DesignWidth="500"
        Title="ExpenseIt - View Expense">
    
        <Grid>
            
        </Grid>
    </Page>
    
  11. Откройте ExpenseItHome.xaml.vb и ExpenseReportPage.xaml.vbили ExpenseItHome.xaml.cs и ExpenseReportPage.xaml.cs.

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

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

    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 ExpenseItHome
    
    End Class
    

    И, как показано ниже для ExpenseReportPage:

    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();
            }
        }
    }
    
    Class ExpenseReportPage
    
    End Class
    
  12. Добавьте в проект образ с именем watermark.png. Вы можете создать собственный образ, скопировать файл из примера кода или получить его из репозитория microsoft/WPF-Samples GitHub.

    1. Щелкните правой кнопкой мыши узел проекта и выберите Добавить>существующий элемент, или нажмите клавиши Shift+Alt+A.

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

    3. Выберите файл изображения вобозревателя решений , а затем в окне свойств установите действие сборки ресурс.

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

  1. Чтобы создать и запустить приложение, нажмите F5 или выберите начать отладку в меню отладки.

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

    приложение после сборки и его запуска.

  2. Закройте приложение, чтобы вернуться в Visual Studio.

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

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

  • Canvas — определяет область, в которой можно явно размещать дочерние элементы, используя координаты, относительные к области Canvas.
  • DockPanel — определяет область, в которой можно упорядочить дочерние элементы по горизонтали или по вертикали относительно друг друга.
  • Grid — определяет гибкую область сетки, состоящую из столбцов и строк.
  • StackPanel — упорядочивает дочерние элементы в одну строку, которая может быть ориентирована по горизонтали или по вертикали.
  • VirtualizingStackPanel — упорядочивает и виртуализирует содержимое в одной строке, ориентированной либо горизонтально, либо вертикально.
  • WrapPanel — позиционирует дочерние элементы в последовательной позиции слева направо, разбивая содержимое в следующую строку по краю содержащего поля. Последующее упорядочение происходит последовательно от верхнего до нижнего или справа налево в зависимости от значения свойства Orientation.

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

Совет

Дополнительные сведения о элементах см. в обзорепанелей . Для получения дополнительной информации о макете см. раздел Layout.

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

  1. В ExpenseItHome.xamlзадайте для свойства Margin элемента Grid значение 10 0 10 10 10, соответствующее левому, верхнему, правому и нижнему полям:

    <Grid Margin="10,0,10,10">
    

    Совет

    Вы также можете задать значения поля в окне свойств в категории макета:

    значения отступов в окне свойств

  2. Добавьте следующий КОД XAML между тегами Grid для создания определений строк и столбцов:

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

    Для Height двух строк задано значение Auto, что означает, что их размер определяется на основе их содержимого. Размер Height по умолчанию — это Star, что означает, что высота строки определяется взвешенной пропорцией доступного пространства. Например, если две строки имеют Height "*", они имеют высоту, которая составляет половину доступного пространства.

    Ваш 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>
    

Добавление элементов управления

В этом разделе вы обновите пользовательский интерфейс домашней страницы, чтобы отобразить список людей, где вы выберете одного человека для отображения отчета о расходах. Элементы управления — это объекты пользовательского интерфейса, позволяющие пользователям взаимодействовать с приложением. Дополнительные сведения см. в элементах управления.

Чтобы создать этот пользовательский интерфейс, вы добавите следующие элементы в ExpenseItHome.xaml:

  • ListBox (для списка людей).
  • Label для заголовка списка.
  • Button (нажмите, чтобы просмотреть отчет о расходах для выбранного в списке человека).

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

  1. В ExpenseItHome.xamlдобавьте следующий КОД 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,10" Width="125" Height="25" HorizontalAlignment="Right">View</Button>
    

    Совет

    Вы также можете создать элементы управления, перетащив их из окна панели элементов в окно конструктора, а затем задав их свойства в окне свойств .

  2. Создайте и запустите приложение.

    На следующем рисунке показаны созданные элементы управления:

образец снимка экрана ExpenseIt, отображающий список имен

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

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

  1. В ExpenseItHome.xamlдобавьте еще один столбец в ColumnDefinitions с фиксированным Width шириной 230 пикселей.

    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="230" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    
  2. Добавьте еще одну строку в RowDefinitions, итого четыре строки.

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition Height="Auto"/>
        <RowDefinition />
        <RowDefinition Height="Auto"/>
    </Grid.RowDefinitions>
    
  3. Переместите элементы управления во второй столбец, установив для свойства Grid.Column значение 1 в каждом из трех элементов управления (Border, ListBox и Button).

  4. Переместите каждый элемент управления вниз по строке, добавив его значение Grid.Row на 1 для каждого из трех элементов управления (Border, ListBox и Button) и для элемента Border.

    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>
    
  5. Задайте свойств у фонового файл изображения watermark.png, добавив следующий XAML в любом месте между тегами <Grid> и </Grid>:

    <Grid.Background>
        <ImageBrush ImageSource="watermark.png"/>
    </Grid.Background>
    
  6. Перед элементом Border добавьте Label с содержимым "Просмотр отчета о расходах". Эта метка является заголовком страницы.

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

На следующем рисунке показаны результаты только что добавленных объектов:

пример снимка экрана ExpenseIt с новым фоном изображения и заголовком страницы

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

  1. В 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>
    
  2. Откройте ExpenseItHome.xaml.vb или ExpenseItHome.xaml.cs.

  3. Добавьте следующий код в класс ExpenseItHome, чтобы добавить обработчик событий нажатия кнопки. Обработчик событий открывает страницу ExpenseReportPage.

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage();
        this.NavigationService.Navigate(expenseReportPage);
    }
    
    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
    

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

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

  1. Откройте ExpenseReportPage.xaml.

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

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

    Этот пользовательский интерфейс аналогичен ExpenseItHome.xaml, за исключением того, что данные отчета отображаются в DataGrid.

  3. Создайте и запустите приложение.

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

    Откроется страница отчета о расходах. Обратите внимание, что включена кнопка навигации назад.

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

пример снимка экрана ExpenseIt, показывающий только что созданный пользовательский интерфейс для ExpenseReportPage.

Элементы управления стилем

Внешний вид различных элементов часто одинаков для всех элементов одного типа в пользовательском интерфейсе. Интерфейс использует стили для применения единого внешнего вида к нескольким элементам. Повторное использование стилей помогает упростить создание и управление 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 см. в разделе Использование ресурсов приложений.

  3. В 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 применяется к «Просмотр отчета о расходах» Label.

  4. Откройте ExpenseReportPage.xaml.

  5. Замените всё, что находится между элементами 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 добавляет стили для элементов Label и Border.

  6. Создайте и запустите приложение. Внешний вид окна совпадает с ранее.

    образец снимка экрана ExpenseIt с таким же внешним видом, как в последнем разделе.

  7. Закройте приложение, чтобы вернуться в Visual Studio.

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

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

  1. В ExpenseItHome.xamlпосле открытия элемента Grid добавьте следующий XAML для создания XmlDataProvider, содержащего данные для каждого человека:

    <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. Обычно эти данные загружаются в виде файла, но для упрощения добавляются непосредственно.

  2. В элементе <Grid.Resources> добавьте следующий элемент <xref:System.Windows.DataTemplate>, определяющий способ отображения данных в ListBoxпосле элемента <XmlDataProvider>:

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

    Дополнительные сведения о шаблонах данных см. в обзоре шаблонов данных.

  3. Замените существующий ListBox следующим кодом XAML:

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

    Этот XAML привязывает свойство ItemsSourceListBox к источнику данных и применяет шаблон данных как ItemTemplate.

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

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

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

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

    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;
        }
    }
    
    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
    
  3. Откройте ExpenseItHome.xaml.vb или ExpenseItHome.xaml.cs.

  4. Измените обработчик событий Click, чтобы вызвать новый конструктор, передав данные отчета о расходах выбранного человека.

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        // View Expense Report
        ExpenseReportPage expenseReportPage = new ExpenseReportPage(this.peopleListBox.SelectedItem);
        this.NavigationService.Navigate(expenseReportPage);
    }
    
    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
    

Стилизуйте данные с помощью шаблонов данных

В этом разделе вы обновите пользовательский интерфейс для каждого элемента в списках, привязанных к данным, с помощью шаблонов данных.

  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. Замените элементы DataGridTextColumnDataGridTemplateColumn в элементе DataGrid и примените к ним шаблоны. Кроме того, укажите атрибут ItemsSource со значением в элементе DataGrid.

    <!-- Expense type and Amount table -->
    <DataGrid ItemsSource="{Binding XPath=Expense}" ColumnHeaderStyle="{StaticResource columnHeaderStyle}" AutoGenerateColumns="False" RowHeaderWidth="0" >
       
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="ExpenseType" CellTemplate="{StaticResource typeItemTemplate}" />
            <DataGridTemplateColumn Header="Amount" CellTemplate="{StaticResource amountItemTemplate}" />
        </DataGrid.Columns>
        
    </DataGrid>
    
  5. Создайте и запустите приложение.

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

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

обе страницы приложения с списком имен и отчетом о расходах.

Заметка

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

Дальнейшие действия

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

Дополнительные сведения о создании приложений см. в следующих разделах:

См. также