Использование островов XAML UWP для размещения элемента управления XAML UWP в приложении WPF C#

Это важно

В этом разделе используются или упоминаются типы из репозитория CommunityToolkit/Microsoft.Toolkit.Win32 GitHub. Сведения о поддержке островов XAML UWP см. в уведомлении XAML Islands в этом репозитории.

В этом разделе показано, как создать приложение Windows Presentation Foundation (WPF) на C# для платформы .NET Core 3.1, использующее UWP XAML Islands для размещения элемента управления XAML платформы универсальных приложений Windows (UWP), то есть собственного элемента управления, предоставленного пакетом Windows SDK. Мы покажем, как это сделать двумя способами:

  • В ней описано, как разместить элементы управления UWP InkCanvas и InkToolbar, используя заключенные в оболочку элементы управления в наборе средств сообщества Windows. Эти элементы управления заключают интерфейс и функциональные возможности небольшого набора полезных элементов управления UWP XAML в оболочку. Вы можете добавить обернутый элемент управления непосредственно на поверхность конструктора вашего проекта WPF или Windows Forms, а затем использовать его в конструкторе, как и любой другой элемент управления WPF или Windows Forms.

  • Мы также покажем, как разместить элемент управления UWP CalendarView с помощью элемента управления WindowsXamlHost (доступно в наборе средств сообщества Windows). Так как в качестве заключенных в оболочку элементов управления доступен только небольшой набор элементов управления UWP XAML, вы можете использовать WindowsXamlHost для размещения любого элемента управления UWP XAML.

Процесс размещения элемента управления XAML UWP в приложении WPF аналогичен Windows Forms приложению.

Это важно

Использование островов XAML UWP (упакованных элементов управления или WindowsXamlHost) для размещения элементов управления XAML UWP поддерживается только в приложениях, предназначенных для .NET Core 3.x. Острова XAML UWP не поддерживаются в приложениях, предназначенных для .NET, или в приложениях, предназначенных для любой версии платформы .NET.

Чтобы разместить элемент управления XAML UWP в приложении WPF или Windows Forms, рекомендуется использовать следующие компоненты в решении. Эта тема содержит инструкции по созданию каждого из этих компонентов.

  • Проект и исходный код для вашего приложения WPF или Windows Forms.

  • A UWP project, определяющий корневой класс приложения, производный от XamlApplication. Класс Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication доступен в наборе средств сообщества Windows). Мы рекомендуем определить производный от XamlApplication класс Application в отдельном проекте приложения UWP, который является частью решения WPF или Windows Forms Visual Studio.

    Замечание

    Создание объекта XamlApplication, доступного для вашего проекта WPF или Windows Forms, фактически не требуется для размещения фирменного элемента управления UWP XAML. Но это необходимо для обнаружения, загрузки и размещения пользовательских элементов управления XAML UWP. Поэтому для поддержки полного диапазона сценариев xaml Island рекомендуется всегда определять объект, производный от XamlApplication, в любом решении, в котором используются острова XAML UWP.

    Замечание

    Решение может содержать только один project, определяющий объект, производный от XamlApplication. Этот проект должен ссылаться на любые другие библиотеки и проекты, которые размещают элементы управления UWP XAML с помощью платформы XAML Islands.

Создание проекта WPF

Эти инструкции можно выполнить, чтобы создать проект WPF и настроить его для размещения островов XAML UWP. Если у вас есть проект WPF, вы можете адаптировать эти шаги и примеры кода для вашего проекта.

  1. Если это еще не сделано, установите последнюю версию .NET Core 3.1.

  2. В Visual Studio создайте project C# из шаблона WPF Application project. Задайте имя проекта значением MyWPFApp, чтобы вам не нужно было изменять какие-либо шаги или исходный код в этом разделе. Задайте для Framework значение .NET Core 3.1*, а затем щелкните Create.

Это важно

Не используйте шаблон приложения WPF (.NET Framework) project.

Настройте проект WPF

  1. Эти шаги позволяют включить ссылки на пакеты package:

    1. В Visual Studio щелкните Tools>NuGet диспетчер пакетов>Параметры диспетчера пакетов.
    2. В правой части найдите параметрУправление пакетами>Формат управления пакетами по умолчанию и задайте для него значение PackageReference.
  2. Чтобы установить пакет NuGet Microsoft.Toolkit.Wpf.UI.Controls, выполните следующие шаги:

    1. Щелкните правой кнопкой узел проекта MyWPFApp в Обозреватель решений и выберите Manage NuGet Packages....

    2. На вкладке Browse введите или вставьте Microsoft.Toolkit.Wpf.UI.Controls в поле поиска. Выберите последнюю стабильную версию и нажмите кнопку Установить. Пакет предоставляет все необходимое для использования обернутых элементов управления UWP XAML в WPF (включая InkCanvas, InkToolbar и элемент управления WindowsXamlHost).

    Замечание

    Для приложения Windows Forms см. вместо него пакет Microsoft.Toolkit.Forms.UI.Controls.

  3. Большинство сценариев XAML островов UWP не поддерживаются в проектах, предназначенных для любого процессора. Чтобы ориентироваться на конкретную архитектуру (например, x86 или x64), выполните следующие действия:

    1. Щелкните правой кнопкой мыши узел решения (не узел проекта) в Обозревателе решений и выберите Свойства.
    2. Выберите Свойства конфигурации слева.
    3. Щелкните Configuration Manager... кнопка .
    4. В списке Active solution platform (Активная платформа решения) выберите пункт Создать.
    5. В диалоговом окне Создание платформы решения выберите x64 или x86 и нажмите кнопку ОК.
    6. Закройте открытые диалоговые окна.

Определение класса XamlApplication в новом project UWP

В этом разделе мы добавим в решение проект UWP и изменим класс по умолчанию App в этом проекте, чтобы он наследовался от класса Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication, предоставленного набором инструментов сообщества Windows. Этот класс поддерживает интерфейс IXamlMetadataProvider, который позволяет приложению обнаруживать и загружать метаданные для настраиваемых элементов управления UWP XAML в сборках в текущем каталоге приложения во время выполнения. Этот класс также инициализирует платформу UWP XAML для текущего потока.

  1. В Обозреватель решений щелкните правой кнопкой мыши узел решения и выберите Add>New Project... .

  2. Выберите шаблон проекта C# Blank App (Universal Windows). Задайте для имени проекта Project значение MyUWPApp, чтобы вам не пришлось изменять какие-либо шаги или исходный код в этом разделе. Установите версию Целевая версия и Минимальная версия на Windows 10 версии 1903 (сборка 18362) или более позднюю.

    Замечание

    Убедитесь, что не создаете MyUWPApp в подкаталоге MyWPFApp. Если это сделать, MyWPFApp попытается создать разметку XAML UWP, как если бы это было WPF XAML.

  3. В MyUWPApp установите пакет NuGet Microsoft.Toolkit.Win32.UI.XamlApplication (последняя стабильная версия). Процесс установки пакета NuGet был описан в предыдущем разделе.

  4. В MyUWPAppоткройте файл App.xaml и замените его содержимое следующим кодом XAML:

    <xaml:XamlApplication
        x:Class="MyUWPApp.App"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:xaml="using:Microsoft.Toolkit.Win32.UI.XamlHost"
        xmlns:local="using:MyUWPApp">
    </xaml:XamlApplication>
    
  5. Затем откройте файл App.xaml.cs и замените его содержимое следующим кодом:

    namespace MyUWPApp
    {
        public sealed partial class App : Microsoft.Toolkit.Win32.UI.XamlHost.XamlApplication
        {
            public App()
            {
                this.Initialize();
            }
        }
    }
    
  6. Удалите файлы MainPage.xaml и MainPage.xaml.cs.

  7. Создайте MyUWPApp project.

В MyWPFApp добавьте ссылку на myUWPApp project

  1. Укажите совместимую версию платформы в файле MyWPFApp project, как показано ниже:

    1. В Обозреватель решений щелкните узел проекта MyWPFApp, чтобы открыть файл проекта в редакторе.

    2. В первый элемент PropertyGroup добавьте следующий дочерний элемент. Измените часть значения 19041, чтобы соответствовать целевой и минимальной сборке ОС MyWPFApp project.

      <AssetTargetFallback>uap10.0.19041</AssetTargetFallback>
      
  2. В Обозреватель решений щелкните правой кнопкой мыши MyWPFApp>Dependencies выберите Add Project Reference... и добавьте ссылку на MyUWPApp project.

Создание экземпляра объекта XamlApplication в точке входа приложения MyWPFApp

Далее добавьте код к точке входа MyWPFApp, чтобы создать экземпляр класса App, который был только что определен в MyUWPApp (класс, производный от XamlApplication).

  1. Щелкните правой кнопкой мыши на узле проекта MyWPFApp, выберите Добавить>Новый элемент..., а затем выберите Класс. В поле Имя укажите Program.cs и нажмите Добавить.

  2. Замените содержимое Program.cs следующим XAML (а затем сохраните файл и создайте файл MyWPFApp project):

    namespace MyWPFApp
    {
        public class Program
        {
            [System.STAThreadAttribute()]
            public static void Main()
            {
                using (new MyUWPApp.App())
                {
                    var app = new MyWPFApp.App();
                    app.InitializeComponent();
                    app.Run();
                }
            }
        }
    }
    
  3. Щелкните правой кнопкой мыши узел MyWPFApp project и выберите Properties.

  4. В разделе Приложение>Общие в раскрывающемся списке Автоматически запускаемый объект выберите MyWPFApp.Program (полное имя только что добавленного класса Program). Если вы этого не видите, попробуйте закрыть и повторно открыть Visual Studio.

    Замечание

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

  5. Сохраните изменения в свойствах проекта.

Используйте обернутые элементы управления для размещения InkCanvas и InkToolbar

Теперь, когда вы настроили проект для использования островов XAML UWP, вы готовы добавить обёрнутые элементы управления InkCanvas и InkToolbar из UWP XAML в ваше приложение.

  1. В MyWPFApp откройте файл MainWindow.xaml.

  2. В элемент Window в верхней части XAML-файла добавьте следующий атрибут. Этот атрибут ссылается на пространство имен XAML для заключенных в оболочку элементов управления XAML UWP класса InkCanvas и InkToolbar и сопоставляет его с пространством имен XML элементов управления.

    xmlns:controls="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls"
    
  3. В MainWindow.xaml измените существующий элемент Grid так, чтобы он выглядел, как показано ниже в XAML. Этот XAML добавляет в Grid элементы управления InkCanvas и InkToolbar с префиксом из пространства имен XML controls, которое вы определили на предыдущем шаге.

    <Grid Margin="10,50,10,10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <controls:InkToolbar x:Name="myInkToolbar" TargetInkCanvas="{x:Reference myInkCanvas}" Grid.Row="0" Width="300"
            Height="50" Margin="10,10,10,10" HorizontalAlignment="Left" VerticalAlignment="Top" />
        <controls:InkCanvas x:Name="myInkCanvas" Grid.Row="1" HorizontalAlignment="Left" Width="600" Height="400"
            Margin="10,10,10,10" VerticalAlignment="Top" />
    </Grid>
    

    Замечание

    Вы также можете добавить эти и другие упакованные элементы управления в Window, перетащив их в конструктор из раздела Windows Community Toolkit на Toolbox.

  4. Сохраните MainWindow.xaml.

    Если у вас есть устройство, поддерживающее цифровое перо (например, Surface), и вы следуете на физическом устройстве, теперь вы можете создать и запустить приложение, а затем рисовать цифровыми чернилами на экране с помощью пера. Но если вы попытаетесь написать с помощью мыши, ничего не произойдет, так как по умолчанию InkCanvas включен только для цифровых перьев. Вот как можно включить InkCanvas для мыши.

  5. В MyWPFAppоткройте MainWindow.xaml.cs.

  6. Добавьте следующую директиву пространства имен в начало файла:

    using Microsoft.Toolkit.Win32.UI.Controls.Interop.WinRT;
    
  7. Откройте конструктор MainWindow. Сразу после вызова метода InitializeComponent добавьте следующую строку кода:

    myInkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen;
    

    Вы можете настроить интерфейс рукописного ввода по умолчанию, используя объект InkPresenter. Код выше использует свойство InputDeviceTypes для поддержки мыши в качестве устройства рукописного ввода.

  8. Сохраните, выполните сборку и запустите. Если вы используете компьютер с мышью, убедитесь, что вы можете нарисовать что-либо с помощью мыши на холсте для рукописного ввода.

Используйте элемент управления-хост для интеграции CalendarView

В этом разделе мы будем использовать элемент управления WindowsXamlHost для добавления элемента управления CalendarView в приложение.

Замечание

Элемент управления WindowsXamlHost предоставляется пакетом Microsoft.Toolkit.Wpf.UI.XamlHost. Этот пакет включён в состав пакета Microsoft.Toolkit.Wpf.UI.Controls, установленного ранее.

  1. В Обозреватель решений в MyWPFApp откройте файл MainWindow.xaml.

  2. В элемент Window в верхней части XAML-файла добавьте следующий атрибут. Этот атрибут ссылается на пространство имен XAML для элемента управления WindowsXamlHost и сопоставляет его с пространством имен XML xamlhost.

    xmlns:xamlhost="clr-namespace:Microsoft.Toolkit.Wpf.UI.XamlHost;assembly=Microsoft.Toolkit.Wpf.UI.XamlHost"
    
  3. В MainWindow.xaml измените существующий элемент Grid так, чтобы он выглядел, как показано ниже в XAML. Этот XAML добавляет в Grid элемент управления WindowsXamlHost, с префиксом пространства имен XML xamlhost, которое вы определили на предыдущем шаге. Чтобы разместить элемент управления UWP CalendarView, этот код XAML задает для свойства InitialTypeName полное имя элемента управления. Этот код XAML также задаёт обработчик для события ChildChanged, которое вызывается при отрисовке размещенного элемента управления.

    <Grid Margin="10,50,10,10">
        <xamlhost:WindowsXamlHost x:Name="myCalendar" InitialTypeName="Windows.UI.Xaml.Controls.CalendarView"
              Margin="10,10,10,10" Width="600" Height="300" ChildChanged="MyCalendar_ChildChanged" />
    </Grid>
    
  4. Сохраните MainWindow.xaml и откройте MainWindow.xaml.cs.

  5. Удалите следующую строку кода, добавленную в предыдущем разделе: myInkCanvas.InkPresenter.InputDeviceTypes = CoreInputDeviceTypes.Mouse | CoreInputDeviceTypes.Pen;.

  6. Добавьте следующую директиву пространства имен в начало файла:

    using Microsoft.Toolkit.Wpf.UI.XamlHost;
    
  7. Добавьте приведенный ниже метод обработчика событий ChildChanged в класс MainWindow. После отрисовки элемента управления, этот обработчик событий запускается и создает простой обработчик событий для события SelectedDatesChanged элемента управления "Календарь".

    private void MyCalendar_ChildChanged(object sender, EventArgs e)
    {
        WindowsXamlHost windowsXamlHost = (WindowsXamlHost)sender;
    
        var calendarView =
            (Windows.UI.Xaml.Controls.CalendarView)windowsXamlHost.Child;
    
        if (calendarView != null)
        {
            calendarView.SelectedDatesChanged += (obj, args) =>
            {
                if (args.AddedDates.Count > 0)
                {
                    MessageBox.Show("The user selected a new date: " +
                        args.AddedDates[0].DateTime.ToString());
                }
            };
        }
    }
    
  8. Сохраните, выполните сборку и запустите. Убедитесь, что в окне отображается элемент управления "Календарь", и при выборе даты отображается окно сообщения.

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

При необходимости можно упаковить приложение WPF в пакете MSIX для развертывания. MSIX — это современная и надежная технология упаковки приложений для Windows.

В следующих инструкциях показано, как упаковать все компоненты решения в MSIX-пакет с помощью проекта Windows Application Packaging Project в Visual Studio (см. Настройка вашего настольного приложения для упаковки в MSIX в Visual Studio). Эти действия необходимы только в том случае, если вы хотите упаковать приложение WPF в пакет MSIX.

Замечание

Если вы решили не упаковывать приложение в пакет MSIX для развертывания, на компьютерах с запущенными приложениями должна быть установлена среда выполнения Visual C++.

  1. Добавьте новый проект в решение, созданное на основе шаблона проекта Упаковка приложений Windows. При создании project выберите ту же версию Target и версию Minimum, что и для project UWP.

  2. В проекте упаковки щелкните правой кнопкой мыши узел Dependencies и выберите Добавить ссылку на проект.... В списке проектов выберите MyWPFApp и нажмите OK.

    Замечание

    Если вы хотите опубликовать приложение в Microsoft Store, то необходимо также добавить ссылку на проект UWP в проект упаковки.

  3. Если вы выполнили все шаги, все проекты в решении будут ориентироваться на одну и ту же конкретную платформу (x86 или x64). И это необходимо для сборки приложения WPF в пакет MSIX с помощью Windows Application Packaging Project. Чтобы убедиться в этом, вы можете выполнить следующие действия:

    1. Щелкните правой кнопкой мыши узел решения (не узел проекта) в Обозревателе решений и выберите Свойства.
    2. Выберите Свойства конфигурации слева.
    3. Щелкните Configuration Manager... кнопка .
    4. Убедитесь, что все перечисленные проекты имеют одно и то же значение в разделе Platform: x86 или x64.
  4. Щелкните правой кнопкой мыши узел проекта для упаковочного проекта, который вы только что добавили, и щелкните Установить как стартовый проект.

  5. Создайте и запустите проект пакетирования. Убедитесь, что приложение WPF запускается, и что элементы управления UWP отображаются должным образом.

  6. Сведения о распространении и развертывании пакета см. в статье Управление развертыванием MSIX.