使用者介面移轉 (包括 WinUI 3)
本主題介紹如何移轉使用者介面 (UI) 程式碼,包括移轉到 WinUI 3。
API 和/或功能差異摘要
Window.Current 屬性會移轉至 App.Window。 而 CoreDispatcher.RunAsync 方法會移轉至 DispatcherQueue.TryEnqueue。
您必須在 MessageDialog 和 Pickers 上設定視窗的處理常式 (HWND)。
若要使用 DataTransferManager API,您必須將它們與您的視窗產生關聯。
針對 ContentDialog 和 Popup,您必須設定其 XamlRoot 屬性。
您可能需要重構 Visual State Manager 和 Page.Resources XAML 標記。
在 Windows 應用程式 SDK 中,AcrylicBrush 一律會從應用程式內容取樣。
將 Windows.UI.Xaml.Window.Current 變更為 App.Window)
如果您在 UWP app 中使用 Windows.UI.Xaml.Window.Current 屬性,則本節適用。 Windows 應用程式 SDK 不支援該屬性,因此本節說明如何移植使用 Window.Current 的 UWP 程序代碼。
// 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 };
您的 Windows 應用程式 SDK 應用程式可以透過使用 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 和 Pickers
在 UWP 應用程式中,如果您使用來自 Windows.UI.Popups 或 Windows.Storage.Pickers 命名空間,然後本節包含可協助您移轉該程式代碼的資訊。 下面的程式碼範例使用 MessageDialog,但您可以應用完全相同的技術來顯示選取器 (例如 FileOpenPicker、FileSavePicker 或 FolderPicker)。
您必須在傳統型應用程式中遵循的步驟,如 顯示相依於 CoreWindow 的 WinRT UI 物件中所述。
注意
針對新的應用程式,我們建議使用 ContentDialog 控制項,而不是 MessageDialog。 如需詳細資訊,請參閱下方的 ContentDialog 和 Popup 一節。
以下是顯示 MessageDialog 的一些一般 UWP 程式代碼。
// 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();
以下是 Windows 應用程式 SDK 應用程式中的對等程序代碼。
// 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 方法,本節會包含可協助您移轉該程式代碼的資訊。
以下是一些呼叫 ShowShareUI 的一般 UWP 程式代碼。
// 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();
若要在 Windows 應用程式 SDK 應用程式中使用 DataTransferManager.ShowShareUI,您必須將共用 UI 與您的視窗產生關聯。 這需要手動完成。 有關詳細資訊和代碼示例,請參閱 顯示依賴於 CoreWindow 的 WinRT UI 物件。
ContentDialog 和 Popup
如果您在 UWP 應用程式中使用 Windows.UI.Xaml.Controls.ContentDialog 或 Windows.UI.Xaml.Controls.Primitives.Popup 類別,則本節包含可協助您移轉該程式代碼的資訊。 下列程式代碼範例使用 ContentDialog,但您可以套用完全相同的技術來顯示 Popup 物件。
以下是顯示 ContentDialog 的一些一般 UWP 程式代碼。
// 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();
在 Windows 應用程式 SDK 應用程式中,您只需要設定對話框的 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 類別的方法中會有導航程式碼,即使您的應用程式足夠簡單,只有一個 Page。
當您在 Visual Studio 中建立新的 Windows 應用程式 SDK 專案時,專案範本會為您提供 MainWindow 類別 (類型為 Microsoft.UI.Xaml.Window),但沒有 Page。 項目範本不會提供任何導覽程序代碼。
對於足夠簡單的 Windows 應用程式 SDK 應用程式 (單頁應用程式),您也許可以簡化它。 您可能不需要在 Windows 應用程式 SDK 專案中建立頁面或使用者控件,而是將該單一頁面的 XAML 標記和程式碼隱藏複製到 MainWindow 中。 不過,MainWindow 不支援某些專案。 Window 不是 DependencyObject,因此其上不存在諸如 Resources 和 DataContext 之類的功能。 Load 和 Unload 等事件也不會發生。 如需詳細資訊和因應措施,請參閱 Visual State Manager 和 Page.Resources。
另一方面,如果您想要或需要在 Windows 應用程式 SDK 應用程式中的頁面之間進行導航,則可以透過從 UWP 應用程式移轉 App.OnLaunched 和 App::On Navigation Failed 方法來實現。 在 App.OnLaunched 中,找到導航程式碼 (建立 rootFrame 並導航到應用程式第一頁的程式碼) 並將其合併到現有的兩行程式碼 (建立視窗然後啟動它的行) 之間。 您也需要移轉您複製貼上的程式碼。 如需簡單的程式代碼範例,請參閱 Page 類別。
Visual State Manager 和 Page.Resources
另請參閱是否需要實作頁面導覽?。 如果您確實有一個足夠簡單的 UWP 應用程序,您可以將 XAML 標記和隱藏代碼複製到 MainWindow 中,那麼請記住這些例外情況。
您的 MainWindow 類別 (類型為 Microsoft.UI.Xaml.Window) 不是控件,因此它不支援 Visual State Manager XAML 標記和程式碼隱藏 (請參閱教學課程:建立自適應佈局)。 不過,您有下列兩個選項:
- 將 UserControl 專案新增至專案,並將標記和程式代碼後置移轉至該專案。 然後將該使用者控制項的執行個體放在 MainWindow 中。
- 將 Page 專案新增至專案,並將標記和程式代碼後置移轉至該專案。 然後將程式碼新增至您的 App 類別以在啟動時導航到該 Page,如我需要實現頁面導航嗎?中所述。
此外,您將無法將元素複製到 <Page.Resources>
MainWindow,而只需將它重新命名為 。<Window.Resources>
相反,在 MainWindow 的 XAML 標記中將 Resources 元素設定為根佈局容器 (例如,Grid) 下的上層。 其看起來將會像下面這樣:
<Window ...>
<Grid>
<Grid.Resources>...</Grid.Resources>
...
</Grid>
</Window>
AcrylicBrush.BackgroundSource property
AcrylicBrush.BackgroundSource 屬性存在於 UWP 中,但不存在於 Windows 應用程式 SDK 中。 在 Windows 應用程式 SDK 中,AcrylicBrush 一律會從應用程式內容取樣。
因此,如果您要在 UWP 應用程式的原始程式碼中存取 AcrylicBrush.BackgroundSource 屬性 (無論是在 XAML 標記或命令式程式代碼中),請在將您的應用程式移轉至 Windows 應用程式 SDK 時移除該程式代碼。 請改用 DesktopAcrylicController 類別。