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


Перенос пользовательского интерфейса (включая WinUI 3)

В этом разделе показано, как перенести код пользовательского интерфейса, включая перенос в WinUI 3.

Сводка различий между API и (или) функциями

Свойство Window.Current переносится в App.Window. И метод CoreDispatcher.RunAsync переносится в DispatcherQueue.TryEnqueue.

Необходимо задать дескриптор окна (HWND) в MessageDialog и в средствавыбора.

Чтобы использовать API DataTransferManager , необходимо связать их с окном.

Для ContentDialog и Всплывающего окна необходимо задать их свойство XamlRoot .

Возможно, потребуется рефакторинг разметки Visual State Manager и Page.Resources XAML.

В пакете SDK для приложений Windows АкрилБруш всегда примеры из содержимого приложения.

Изменение Windows.UI.Xaml.Window.Current на App.Window

Этот раздел применяется, если вы используете свойство Windows.UI.Xaml.Window.Current в приложении UWP. Это свойство не поддерживается в пакете SDK для приложений Windows, поэтому в этом разделе описывается перенос кода UWP, использующего Window.Current.

// MainPage.xaml.cs in a UWP app
var width = Window.Current.Bounds.Width;
// MainPage.xaml.cpp in a UWP app
auto width{ Window::Current().Bounds().Width };

Приложение пакета SDK для приложений Windows может добавить собственное понятие текущего или главного окна с помощью общедоступного статического свойства в классе App.

// App.xaml.cs in a Windows App SDK app
public partial class App : Application
{
    ...
    public static Window Window { get { return m_window; } }
    private static Window m_window;
}
// App.xaml.h in a Windows App SDK app
...
struct App : AppT<App>
{
    ...
    static winrt::Microsoft::UI::Xaml::Window Window(){ return window; };

private:
    static winrt::Microsoft::UI::Xaml::Window window;
};
...

// App.xaml.cpp
...
winrt::Microsoft::UI::Xaml::Window App::window{ nullptr };
...

Затем, в самом классе App , вы можете просто измениться Window.Current window. За пределами класса App измените Window.Current значение App.Windowследующим образом:

// MainPage.xaml.cs in a UWP app
var width = App.Window.Bounds.Width;
// MainPage.xaml.cpp in a UWP app
#include <App.xaml.h>
auto width{ App::Window().Bounds().Width };

MessageDialog и средства выбора

В приложении UWP, если вы используете определенные типы из пространств имен Windows.UI.Popups или Windows.Storage.Pickers, этот раздел содержит сведения, которые помогут вам перенести этот код. В приведенных ниже примерах кода используется MessageDialog, но вы можете применить точно те же методы для отображения средства выбора (например, FileOpenPicker, FileSavePicker или FolderPicker).

Действия, которые необходимо выполнить в классическом приложении, описаны в разделе "Отображение объектов пользовательского интерфейса WinRT", зависящих от CoreWindow.

Примечание.

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

Ниже приведен некоторый типичный код UWP для отображения MessageDialog.

// In a UWP app
var showDialog = new Windows.UI.Popups.MessageDialog("Message here");
await showDialog.ShowAsync();
// In a UWP app
auto showDialog{ Windows::UI::Popups::MessageDialog(L"Message here") };
co_await showDialog.ShowAsync();

И вот эквивалентный код в приложении пакета SDK для приложений для Приложений Windows.

// MainWindow.xaml.cs in a WinUI 3 app
var showDialog = new Windows.UI.Popups.MessageDialog("Message here");
WinRT.Interop.InitializeWithWindow.Initialize(showDialog,
    WinRT.Interop.WindowNative.GetWindowHandle(this));
await showDialog.ShowAsync();
// pch.h in a WinUI 3 app
...
#include <Shobjidl.h>
#include <microsoft.ui.xaml.window.h>
#include <winrt/Windows.UI.Popups.h>
...

// MainWindow.xaml.cpp
...
auto showDialog{ Windows::UI::Popups::MessageDialog(L"Message here") };

auto windowNative{ this->m_inner.as<::IWindowNative>() };
HWND hWnd{ 0 };
windowNative->get_WindowHandle(&hWnd);
showDialog.as<::IInitializeWithWindow>()->Initialize(hWnd);

co_await showDialog.ShowAsync();

DataTransferManager

В приложении UWP при вызове метода DataTransferManager.ShowShareUI этот раздел содержит сведения, которые помогут вам перенести этот код.

Вот некоторый типичный код UWP, который вызывает ShowShareUI.

// In a UWP app
var dataTransferManager = Windows.ApplicationModel.DataTransfer.DataTransferManager.GetForCurrentView();

dataTransferManager.DataRequested += (sender, args) =>
{
    args.Request.Data.Properties.Title = "In a UWP app...";
    args.Request.Data.SetText("...display the user interface for sharing content with another app.");
    args.Request.Data.RequestedOperation =
        Windows.ApplicationModel.DataTransfer.DataPackageOperation.Copy;
};

Windows.ApplicationModel.DataTransfer.DataTransferManager.ShowShareUI();
// In a UWP app
#include <winrt/Windows.ApplicationModel.DataTransfer.h>
...
auto dataTransferManager{ Windows::ApplicationModel::DataTransfer::DataTransferManager::GetForCurrentView() };

dataTransferManager.DataRequested([](Windows::ApplicationModel::DataTransfer::DataTransferManager const& /* sender */,
    Windows::ApplicationModel::DataTransfer::DataRequestedEventArgs const& args)
    {
        args.Request().Data().Properties().Title(L"In a UWP app...");
        args.Request().Data().SetText(L"...display the user interface for sharing content with another app.");
        args.Request().Data().RequestedOperation(Windows::ApplicationModel::DataTransfer::DataPackageOperation::Copy);
    });

Windows::ApplicationModel::DataTransfer::DataTransferManager::ShowShareUI();

Чтобы использовать DataTransferManager.ShowShareUI в приложении пакета SDK для приложений Для Windows, необходимо связать пользовательский интерфейс Общего доступа с окном. И это необходимо сделать вручную. Дополнительные сведения и примеры кода см. в разделе "Отображение объектов пользовательского интерфейса WinRT", зависящих от CoreWindow.

ContentDialog и Всплывающее окно

Если в приложении UWP вы используете классы Windows.UI.Xaml.Controls.ContentDialog или Windows.UI.Xaml.Controls.Primitives.Popup, в этом разделе содержатся сведения, помогающие перенести этот код. В приведенных ниже примерах кода используется ContentDialog, но вы можете применить точно те же методы для отображения объекта Popup .

Ниже приведен некоторый типичный код UWP для отображения ContentDialog.

// MainPage.xaml.cs in a UWP app
var unsupportedFilesDialog = new ContentDialog();
// Set Title, Content, etc.
await unsupportedFilesDialog.ShowAsync();
// MainPage.xaml.cpp in a UWP app
ContentDialog unsupportedFilesDialog{};
// Set Title, Content, etc.
co_await unsupportedFilesDialog.ShowAsync();

В приложении пакета SDK для приложений для Windows необходимо также задать свойство XamlRoot диалогового окна. Это делается следующим образом.

// MainPage.xaml.cs in a Windows App SDK app
var unsupportedFilesDialog = new ContentDialog();
// Set Title, Content, etc.
unsupportedFilesDialog.XamlRoot = this.Content.XamlRoot;
await unsupportedFilesDialog.ShowAsync();
// MainPage.xaml.cpp in a Windows App SDK app
ContentDialog unsupportedFilesDialog{};
// Set Title, Content, etc.
unsupportedFilesDialog.XamlRoot(this->Content().XamlRoot());
co_await unsupportedFilesDialog.ShowAsync();

Нужно ли реализовать навигацию по страницам?

В проекте UWP по умолчанию будет код навигации в методах класса App , даже если приложение достаточно простое, что оно имеет только одну страницу.

При создании проекта пакета SDK для приложений Windows в Visual Studio шаблон проекта предоставляет класс MainWindow (типа Microsoft.UI.Xaml.Window), но нет страницы. И шаблон проекта не предоставляет код навигации.

Для приложения пакета SDK для приложений Windows, достаточно простого (одностраничного приложения), вы можете упростить его. Возможно, вам не нужно создавать страницы или пользовательские элементы управления в проекте пакета SDK для приложений Для Windows, а копировать разметку XAML и код за ней в MainWindow. Однако есть некоторые вещи, которые MainWindow не поддерживает. Окно не является зависимостямиObject, поэтому такие возможности, как ресурсы и DataContext , не существуют в нем. Не выполняются такие события, как загрузка и выгрузка. Дополнительные сведения и обходные пути см. в разделе "Диспетчер визуальных состояний" и "Page.Resources".

Если с другой стороны требуется или нужна навигация между страницами в приложении ПАКЕТА SDK для приложений Для Windows, это можно сделать, переносив методы App.OnLaunched и App::OnNavigationFailed из приложения UWP. В App.OnLaunched найдите код навигации (код, который создает корневой кадр и переходит на первую страницу приложения) и объедините его прямо между двумя существующими строками кода (строки, создающие окно, а затем активируйте его). Вам также потребуется перенести скопированный код. Простой пример кода см . в классе Page.

Визуальный диспетчер состояний и Page.Resources

Также см. статью " Нужно ли реализовать навигацию по страницам?". Если у вас есть приложение UWP, достаточно простое, где можно скопировать разметку XAML и код программной части в MainWindow, и помните об этих исключениях.

Класс MainWindow (типа Microsoft.UI.Xaml.Window) не является элементом управления, поэтому он не поддерживает разметку XAML visual State Manager и код позади (см. руководство. Создание адаптивных макетов). У вас есть два варианта, однако:

  • Добавьте элемент UserControl в проект и перенесите в нее разметку и код. Затем поместите экземпляр этого пользовательского элемента управления в MainWindow.
  • Добавьте элемент страницы в проект и перенесите в нее разметку и код. Затем добавьте код в класс приложения, чтобы перейти к этой странице при запуске, как описано в разделе "Необходимо ли реализовать навигацию по страницам?".

Кроме того, вы не сможете скопировать <Page.Resources> элемент в MainWindow и просто переименовать его <Window.Resources>в . Вместо этого родительский элемент Resources в контейнере корневого макета (например, Сетка) в разметке XAML для MainWindow. Это будет выглядеть следующим образом:

<Window ...>
    <Grid>
        <Grid.Resources>...</Grid.Resources>
        ...
    </Grid>
</Window>

Свойство AcrylicBrush.BackgroundSource

Свойство AcrylicBrush.BackgroundSource существует в UWP, но не в пакете SDK для приложений Windows. В пакете SDK для приложений Windows АкрилБруш всегда примеры из содержимого приложения.

Таким образом, если вы обращаетесь к свойству AcrylicBrush.BackgroundSource в исходном коде приложения UWP (будь то в разметке XAML или в императивном коде), удалите этот код при переносе приложения в пакет SDK приложений Windows. Вместо этого используйте класс DesktopAcrylicController .