Linguagem
Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este tópico mostra como migrar o código da sua interface de utilizador (UI), incluindo a migração para o WinUI.
Resumo das diferenças de API e/ou recursos
A propriedade Window.Current migra para App.Window. E o método CoreDispatcher.RunAsync é transferido para o método DispatcherQueue.TryEnqueue.
Você precisa definir o identificador de da janela (HWND) em um MessageDialoge em Pickers.
Para usar DataTransferManager APIs, você precisa associá-las à sua janela.
Para ContentDialog e Popup, é necessário definir a sua propriedade XamlRoot.
Talvez seja necessário refatorar o Visual State Manager e a marcação XAML em Page.Resources.
No SDK de Aplicações Windows, o AcrylicBrush recolhe sempre amostras do conteúdo da app.
Altere Windows.UI.Xaml.Window.Current para App.Window
Esta seção se aplica se você estiver usando a propriedadeWindows.UI.Xaml.Window.Current em seu aplicativo UWP. Essa propriedade não é suportada no SDK de Aplicações Windows, por isso esta secção descreve como portar 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 };
A tua aplicação SDK de Aplicações Windows pode adicionar a sua própria noção de janela corrente ou main usando uma propriedade pública estática na tua classe 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 };
...
Em seguida, dentro da própria classe App, você pode alterar Window.Current para simplesmente window. Fora da classe do App, altere 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 seletores
Na tua aplicação UWP, se usares certos tipos do Windows.UI.Popups ou Windows. Storage. Pickers namespaces, depois esta secção contém informações para te ajudar a migrar esse código. Os exemplos de código abaixo usam MessageDialog, mas pode aplicar exatamente as mesmas técnicas para exibir um seletor (por exemplo, um FileOpenPicker, um FileSavePicker, ou um FolderPicker).
As etapas que tem de seguir numa aplicação de ambiente de trabalho são descritas em Exibir objetos da interface do utilizador do WinRT que dependem do CoreWindow.
Observação
Para novas aplicações, recomendamos usar o controlo 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 numa aplicação do SDK de Aplicações Windows.
// MainWindow.xaml.cs in a WinUI 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 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étodoDataTransferManager.ShowShareUI, esta seção conterá informações para ajudá-lo 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 na sua aplicação de SDK de Aplicações Windows, precisa de associar a interface de partilha à sua janela. E isso precisa ser feito manualmente. Para obter mais informações e exemplos de código, consulte Exibir objetos da interface do usuário do WinRT que dependem do CoreWindow.
ContentDialog, e Popup
Se na sua aplicação UWP estiver a usar as classes Windows.UI.Xaml.Controls.ContentDialog ou Windows.UI.Xaml.Controls.Primitives.Popup, esta secção contém informações para o ajudar a migrar o 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();
Na tua aplicação SDK de Aplicações Windows, só precisas de definir também a propriedade XamlRoot do diálogo. Veja como.
// 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 na página?
Num projeto UWP, por defeito haverá código de navegação nos métodos da classe App, mesmo que a sua aplicação seja suficientemente simples para ter apenas uma Página.
Quando criar um novo projeto SDK de Aplicações Windows no Visual Studio, o modelo de projeto fornece-lhe uma classe MainWindow (do tipo Microsoft.UI.Xaml.Window), mas não existe Page. E o modelo do projeto não fornece nenhum código de navegação.
Para uma aplicação do SDK de Aplicações Windows que seja suficientemente simples (uma aplicação de página única), talvez consigas simplificá-la. Pode ser que não precises de criar páginas ou controlos de utilizador no teu projeto do SDK de Aplicações Windows — mas sim copiar a marcação XAML e o código subjacente da página única para MainWindow. No entanto, há algumas coisas que MainWindow não suporta. Window não é um DependencyObject, portanto, recursos como Resources e DataContext não existem nele. Também não os eventos como Load e Unload. Para obter mais informações e soluções alternativas, consulte Visual State Manager e Page.Resources.
Se, por outro lado, quiser ou precisar de navegar entre páginas na sua aplicação de SDK de Aplicações Windows, pode fazê-lo migrando os métodos App.OnLaunched e App::OnNavigationFailed da sua aplicação 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 entre as duas linhas de código existentes (as linhas que criam uma janela e a ativam). Você também precisará migrar o código que já copiou e colou. Para obter um exemplo de código simples, consulte classe Page.
Gestor de Estado Visual e Recursos de Página
Consulte também Preciso implementar a navegação na página?. Se você tem um aplicativo UWP simples o suficiente para copiar sua marcação XAML e code-behind para MainWindow, tenha em mente essas 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 adaptáveis). No entanto, você tem estas duas opções:
- Adiciona um item UserControl ao projeto e migra a tua marcação e código-behind para esse item. Em seguida, coloque uma instância desse controle de usuário em MainWindow.
- Adicione um item Page ao projeto e migre a sua marcação e código subjacente para esse. Em seguida, adicione código à sua classe App 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 apenas renomeá-lo para <Window.Resources>. Em vez disso, associe o elemento Resources ao container de layout raiz (por exemplo, um Grid) na marcação XAML para o MainWindow. Ficará assim:
<Window ...>
<Grid>
<Grid.Resources>...</Grid.Resources>
...
</Grid>
</Window>
AcrylicBrush.BackgroundSource propriedade
A propriedade AcrylicBrush.BackgroundSource existe no UWP, mas não no SDK de Aplicações Windows. No SDK de Aplicações Windows, o AcrylicBrush recolhe sempre amostras do conteúdo da app.
Portanto, se estiveres a aceder à propriedade AcrylicBrush.BackgroundSource no código-fonte da tua aplicação UWP (seja em marcação XAML ou em código imperativo), remove esse código ao migrar a tua aplicação para a SDK de Aplicações Windows. Em vez disso, use a classe DesktopAcrylicController.
DisplayInformation.GetForCurrentView
No UWP, o DisplayInformation.GetForCurrentView() fornece informações de DPI, fator de escala e orientação. Nas aplicações de ambiente de trabalho do WinUI 3, esta API gera uma exceção porque não há CoreWindow. Utilize XamlRoot.RasterizationScale em vez disso e subscreva o evento XamlRoot.Changed para responder a alterações no DPI.
// UWP
var displayInfo = DisplayInformation.GetForCurrentView();
double scale = displayInfo.RawPixelsPerViewPixel;
// WinUI 3
double scale = myElement.XamlRoot.RasterizationScale;
myElement.XamlRoot.Changed += (sender, args) =>
{
double newScale = sender.RasterizationScale;
// Respond to DPI change
};
Para obter a resolução real do ecrã, use APIs do Win32, como GetDpiForWindow, com o HWND da janela.
Comportamento de lista virtualizada com marcador de lugar nulo
O ListView e o GridView da UWP toleram null itens na respetiva origem de dados ao utilizar virtualização com IItemsRangeInfo. O WinUI 3 não — itens nulos causam uma falha E_POINTER (0x80004003) em tempo de execução.
Se a sua fonte de dados UWP utilizar null como marcador de posição para itens ainda não carregados, substitua esses valores por um objeto sentinela não nulo:
// UWP — tolerated null placeholders
items[index] = null; // Placeholder for unloaded item
// WinUI 3 — use a non-null placeholder
items[index] = new PlaceholderItem(); // Any non-null object
Verifique também se a sua implementação de IList ou IVector nunca devolve null no respetivo indexador para os intervalos que o WinUI 3 solicita através de IItemsRangeInfo.
Atributo de origem da imagem vazio
No UWP, definir <Image Source="" /> ou Source="{x:Null}" não causa problemas. No WinUI 3, uma cadeia vazia no Source atributo causa um crash rápido no arranque.
Para corrigir isto, ou se omite completamente a Source propriedade ou se usa uma ligação condicional:
<!-- Don't do this in WinUI 3 -->
<Image Source="" />
<!-- Do this instead — omit Source, set it in code when ready -->
<Image x:Name="myImage" />
// Set Source only when you have a valid URI
if (!string.IsNullOrEmpty(imageUri))
{
myImage.Source = new BitmapImage(new Uri(imageUri));
}
Tópicos relacionados
Windows developer