共用方式為


WinUI 和 Windows App SDK 的視窗化概觀

WinUI 應用程式中的視窗化功能是由 XAML Window 類別和 AppWindow 類別的組合所提供,兩者都是以 Win32 HWND 模型為基礎。

WinUI 3 Gallery 應用程式包含大部分 WinUI 3 控制項、特性和功能的互動式範例。 從 Microsoft Store 取得應用程式,或在 GitHub 上取得原始程式碼

XAML Window

在您的應用程式中,window 物件是代表程式代碼中視窗 的 Microsoft.UI.Xaml.Window 類別實例(或衍生類別)。 您可以直接使用對建構函式的呼叫來建立它。 XAML Window 是您附加應用程式內容並管理應用程式視窗生命週期的位置。

HWND

應用程式視窗是由Windows作系統所建立,並以 Win32 視窗物件表示。 這是一個系統管理的容器,其中裝載您的內容,並代表使用者在調整應用程式大小並在螢幕上移動時與其互動的實體。 (如需詳細資訊,請參閱 Win32 檔中的 About Windows 。)

在 Windows 建立應用程式視窗之後,建立函式會傳回唯一地識別該視窗的 window handleHWND)。 window handle 具有 HWND 資料型別,雖然其在 C# 中呈現為 IntPtr。 它是不透明的內部數據結構句柄 Windows,對應於作業系統所繪製的視窗,並在存在時消耗系統資源。

HWND 會在 XAML Window 物件之後建立,通常是在呼叫 Window.Activate 方法時。

AppWindow

Windows App SDK 透過 Microsoft.UI.Windowing 類別提供額外的視窗功能AppWindow。 AppWindow 表示 HWND 的高階抽象概念。 你的應用程式中的AppWindow 與最上層 HWND 之間有 1:1 對應。 AppWindow 及其相關類別提供 API,可讓您管理應用程式最上層視窗的許多層面,而不需要直接存取 HWND。

物件和 HWND 的 AppWindow 存留期相同— AppWindow 在建立窗口之後立即可供使用;當窗口關閉時就會終結。

視窗 API 圖示

此圖顯示您用來管理應用程式中視窗的類別和 API 之間的關聯性,以及哪些類別負責視窗管理的每個部分。 在某些情況下,例如 ExtendsContentIntoTitleBar,API 是 的成員 AppWindow ,可供其他 UI 架構使用,但也會在 類別上 Window 公開,以方便使用。 圖表並不完整,但會顯示最常用的 API。

win u i 視窗化圖表

備註

您可以使用 AppWindow API 搭配 App SDK 支援的任何 UI 架構 Windows - Win32、WPF、WinForms 或 WinUI 3。 對於 WinUI 3 以外的架構,圖表的 XAML Window 方塊中顯示的功能將會由適當的架構特定視窗 API 取代:

Window/AppWindow API 比較

如果您使用 WinUI 3 XAML 作為應用程式的 UI 架構, WindowAppWindow API 都可供您使用。 從 Windows App SDK 1.4 開始,您可以使用 Window.AppWindow 屬性從現有的 XAML 視窗取得 AppWindow 物件。 AppWindow使用此物件時,您可以存取其他視窗管理 API。

這很重要

如果您未使用 WinUI 3 1.3 或更新版本,請使用 Interop API 來取得 AppWindow 以使用 AppWindow API。 如需更多有關互通性 API 的詳細資訊,請參閱 管理應用程式視窗 - 使用者介面框架和 HWND 互通性窗口畫廊範例

終身管理

XAML Window AppWindow
Constructor 建立GetFromWindowId
Activate 顯示隱藏
關閉關閉 銷毀銷毀中關閉
>>> 識別碼OwnerWindowId

當您在 Visual Studio 中建立新的 WinUI 專案時,專案範本會為您提供類別 MainWindow ,這是 的 Window子類別。 如果您的應用程式只需要一個視窗,這就是您所需要的一切。 若要瞭解如何建立和管理其他視窗,以及您可能想要的原因,請參閱 顯示應用程式的多個視窗

類別 AppWindow 有 API 可建立和終結新的視窗;不過,針對 WinUI 應用程式,您實際上不會這麼做,因為沒有 API 可附加內容至您所建立的視窗。 相反地,您會取得由系統建立並與 XAML AppWindow 和 HWND 相關聯的 Window 實例。 在 WinUI 1.4 和更新版本中,您可以使用 Window.AppWindow 屬性來取得 的 AppWindow實例。 在其他情況下,您可以使用靜態 AppWindow。GetFromWindowId 方法可取得 AppWindow 實例。 如需詳細資訊,請參閱 管理應用程式視窗

Content

XAML Window AppWindow
Content N/A

WindowContent 屬性是您將應用程式內容附加至顯示它的視窗的位置。 您可以在 XAML 或程式碼中執行此動作。

標題、圖示和標題列

XAML Window AppWindow
標題 標題
SetTitleBar TitleBar
>>> SetIconSetTaskbarIconSetTitleBarIcon
ExtendsContentIntoTitleBar AppWindow.標題列。內容延伸到標題欄

您可以將應用程式的標題列修改為不同程度;設定標題和圖示、變更色彩,或將標題列完全取代為自定義應用程式內容。

如需使用標題列 API 的詳細資訊,包括程式代碼範例,請參閱 標題列自定義

大小與位置

XAML Window AppWindow
Bounds PositionSizeClientSize
大小已變更 已變更DidPositionChangeDidSizeChange
>>> MoveResize、ResizeClientMoveAndResize
>>> MoveInZOrderAtBottomMoveInZOrderAtTopMoveInZOrderBelow

您可以使用 Window 屬性和 SizeChanged 事件來管理應用程式的 UI,例如在視窗大小改變時調整元素的位置。 XAML 使用 effective pixels (epx),而不是實際的實體圖元。 Effective pixels 是一個虛擬測量單位,用來表示與螢幕密度無關的版面配置尺寸和間距。

AppWindow另一方面,使用 Window 座標系統,其中基本度量單位是實體 裝置圖元。 您可以使用 AppWindow API 進行視窗化動作,例如調整視窗大小,或將視窗相對於畫面上其他項目移動。

在某些情況下,您可能需要在一個類別中使用來自另一個類別的度量,在這種情況下,您必須在effective pixels和裝置圖元之間進行轉換。 例如,如果您在自定義標題欄中設定拖曳區域,則必須轉換度量。 如需如何使用 XamlRoot.RasterizationScale 轉換度量的範例,請參閱標題欄自定義文章的互動式內容一節。

外觀和行為

XAML Window AppWindow
系統背景 N/A
>>> 簡報者SetPresenter
>>> IsShownInSwitchers
可見、可見性變更 IsVisibleChangedDidVisibilityChange
DispatcherQueue DispatcherQueueAssociateWithDispatcherQueue
Compositor N/A

XAML Window API 通常負責應用程式內容的外觀,例如背景。 如需 SystemBackdrop 的詳細資訊,請參閱 套用 Mica 或壓克力材質

AppWindow API 負責視窗 的非用戶端 部分,以及應用程式與 Windows OS 的互動。

備註

XAML Window 類別有數個屬性是從 UWP Windows.UI.Xaml.Window 類別繼承過來的,但在 WinUI 應用程式中不受支援。 這些屬性一律具有 null 值,而且不會用於 WinUI 應用程式: CoreWindowCurrentDispatcher

追蹤目前的視窗

即使 Current WinUI 應用程式中不支援 屬性,您仍可能需要從應用程式中的其他位置存取 Window API。 例如,您可能需要從程式碼取得Window邊界,或處理 Window 的.SizeChanged 事件。 在此情況下,您可以透過在類別 Window 上使用公用靜態屬性,以類似於 Current 屬性的方式提供對 App 的存取。

若要這樣做,請修改 Window App 類別中的宣告,如下所示。

// App.xaml.cs in a WinUI app
public partial class App : Application
{
    ...
    public static Window Window { get { return m_window; } }
    private static Window m_window;
}
// App.xaml.h in a WinUI 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 };
...

然後,若要從應用程式中的其他位置存取 Window ,請使用 App.Window,如下所示:

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

這很重要

如果您的應用程式只使用單一視窗,則在您的類別中使用Window靜態App屬性會很有用。 如果您的應用程式使用多個視窗,您應該改用 WindowId 來追蹤 Window 實例,以確保您存取正確的 實例 Window。 如需詳細資訊和範例,請參閱 顯示應用程式的多個視窗