Compartilhar via


Migração de interface do usuário (incluindo WinUI 3)

Este tópico mostra como migrar o código da interface do usuário, incluindo a migração para o WinUI 3.

Resumo das diferenças de API e/ou recursos

A propriedade Window.Current migra para App.Window. E o método CoreDispatcher.RunAsync migra para DispatcherQueue.TryEnqueue.

É necessário definir o manipulador (HWND) de sua janela em um MessageDialog, e no Pickers.

Para usar APIs DataTransferManager, é necessário associá-las à sua janela.

Para ContentDialog e Popup, você precisa definir sua propriedade XamlRoot.

Talvez seja necessário refatorar a marcação XAML do Visual State Manager e Page.Resources.

No SDK de Aplicativo do Windows, o AcrylicBrush sempre obtém amostras do conteúdo do aplicativo.

Altere Windows.UI.Xaml.Window.Current para App.Window

Esta seção é aplicável se você estiver usando a propriedade Windows.UI.Xaml.Window.Current em seu aplicativo UWP. Essa propriedade não tem suporte no SDK de Aplicativo do Windows, portanto, esta seção descreve como portar o código UWP que usa 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 };

Seu aplicativo SDK de Aplicativo do Windows pode adicionar sua própria noção de uma janela atual ou principal usando uma propriedade estática pública em sua classe Aplicativo.

// 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 };
...

Em seguida, dentro da própria classe Aplicativo, você pode alterar Window.Current para simplesmente window. Fora da classe App, mude Window.Current para App.Window da seguinte forma:

// 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 e Pickers

Em seu aplicativo UWP, se você usar determinados tipos dos namespaces Windows.UI.Popups ou Windows.Storage.Pickers, esta seção conterá informações para ajudar você a migrar esse código. Os exemplos de código abaixo usam MessageDialog, mas você pode aplicar exatamente as mesmas técnicas para exibir um seletor (por exemplo, um FileOpenPicker, um FileSavePicker ou um FolderPicker).

As etapas que você precisa seguir em um aplicativo de área de trabalho são descritas em Exibir objetos de interface do usuário do WinRT que dependem do CoreWindow.

Observação

Para novos aplicativos, recomendamos usar o controle ContentDialog em vez de MessageDialog. Para obter mais informações, consulte a seção ContentDialog e Popup abaixo.

Aqui está um código UWP típico para exibir um 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();

E aqui está o código equivalente em um aplicativo SDK de Aplicativo do 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

Em seu aplicativo UWP, se você chamar o método DataTransferManager.ShowShareUI esta seção conterá informações para ajudar você a migrar esse código.

Aqui está um código UWP típico que chama 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();

Para usar DataTransferManager.ShowShareUI em seu aplicativo de SDK de Aplicativo do Windows, você precisa associar a interface do usuário de compartilhamento à sua janela. Isso precisa ser feito manualmente. Para saber mais e ver exemplos de código, confira Exibir objetos da interface do usuário do WinRT que dependem do CoreWindow.

ContentDialog e Popup

Se você estiver usando as classes Windows.UI.Xaml.Controls.ContentDialog ou Windows.UI.Xaml.Controls.Primitives.Popup, esta seção contém informações para ajudar você a migrar esse código. Os exemplos de código abaixo usam ContentDialog, mas você pode aplicar exatamente as mesmas técnicas para exibir um objeto Popup .

Aqui está um código UWP típico para exibir um 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();

Em seu aplicativo de SDK de Aplicativo do Windows, você só precisa definir também a propriedade XamlRoot da caixa de diálogo. Veja aqui como fazer isso.

// 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();

Preciso implementar a navegação de página?

Em um projeto UWP, por padrão, haverá código de navegação nos métodos da classe App, mesmo que seu aplicativo seja simples o suficiente para que ele tenha apenas uma Página.

Quando você cria um novo projeto do SDK de Aplicativos Windows no Visual Studio, o modelo de projeto fornece uma classe MainWindow (do tipo Microsoft.UI.Xaml.Window), mas nenhuma Página. E o modelo de projeto não fornece nenhum código de navegação.

Para um aplicativo de SDK de Aplicativo do Windows que é simples o suficiente (um aplicativo de página única), talvez seja possível simplificá-lo. Pode ser que você não precise criar páginas ou controles de usuário em seu projeto do SDK de Aplicativo do Windows, mas sim copiar a marcação XAML e o code-behind dessa única página para MainWindow. No entanto, há algumas coisas que o MainWindow não permite. Window não é um DependencyObject, portanto, as funções como Recursos e DataContext não existem nele. Eventos como Carregar e Descarregar também não existem. Para obter mais informações e soluções alternativas, consulte Visual State Manager e Page.Resources.

Por outro lado, se você quiser ou precisar de navegação entre páginas no seu aplicativo de SDK de Aplicativo do Windows, poderá fazer isso migrando os métodos App.OnLaunched e App::OnNavigationFailed do seu aplicativo UWP. Em App.OnLaunched, localize o código de navegação (o código que cria rootFrame e navega até a primeira página do seu aplicativo) e mescle-o diretamente entre as duas linhas de código existentes (as linhas que criam uma janela e a ativam). Também será necessário migrar o código que você copiou e colou. Para obter um exemplo de código simples, consulte classe Página.

Visual State Manager e Page.Resources

Consulte também Preciso implementar a navegação de página?. Se você tiver um aplicativo UWP simples o suficiente para copiar sua marcação XAML e code-behind para MainWindow, lembre-se dessas exceções.

Sua classe MainWindow (do tipo Microsoft.UI.Xaml.Window) não é um controle, portanto, não oferece suporte à marcação XAML do Visual State Manager e ao code-behind (consulte Tutorial: criar layouts adaptativos). No entanto, você tem estas duas opções:

  • Adicione um item UserControl ao projeto e migre sua marcação e code-behind para ele. Em seguida, coloque uma instância desse controle de usuário em MainWindow.
  • Adicione um item Página ao projeto e migre sua marcação e code-behind para ele. Em seguida, adicione código à sua classe Aplicativo para navegar até essa Página na inicialização, conforme descrito em Preciso implementar a navegação de página?.

Além disso, você não poderá copiar um elemento <Page.Resources> para MainWindow e simplesmente renomeá-lo para <Window.Resources>. Em vez disso, crie o elemento Recursos no contêiner de layout raiz (por exemplo, uma Grade) na marcação XAML para MainWindow. Ele terá a seguinte aparência:

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

Propriedade AcrylicBrush.BackgroundSource

A propriedade AcrylicBrush.BackgroundSource existe na UWP, mas não no SDK de Aplicativo do Windows. No SDK de Aplicativo do Windows, o AcrylicBrush sempre obtém amostras do conteúdo do aplicativo.

Portanto, se você estiver acessando a propriedade AcrylicBrush.BackgroundSource no código-fonte do seu aplicativo UWP (seja na marcação XAML ou no código imperativo), remova esse código ao migrar seu aplicativo para o SDK de Aplicativo do Windows. Em vez disso, use a classe DesktopAcrylicController.