用 winui 3 開發了一個摸魚應用

用 winui 3 開發了一個摸魚應用

不要小看摸魚,所有天才的點子都不是敲鍵盤時激發的。在工作遇到阻滯時,越是投入工作越是找不到解決方案,這時候把目光從屏幕挪開,說不定在一邊洗澡一邊玩著小黃鴨時,一邊發呆一邊看著窗外時,一邊睡覺一邊扣肚子時,解決問題的靈感突然就掉進了腦海里。

最后更新 2021/12/16 下午8:51
dino.c
预计阅读 7 分钟
分类
.NET
标签
.NET C# WinUI 3

1. 開發了一個摸魚 app

我做了一個簡單的 app:摸魚。

如上圖所示,這個 app 就只有一個按鈕,點擊後假裝開始 windows update,然後用戶就可以光明正大地摸魚了。

不要小看摸魚,所有天才的點子都不是敲鍵盤時激發的。在工作遇到阻滯時,越是投入工作越是找不到解決方案,這時候把目光從屏幕挪開,說不定在一邊洗澡一邊玩著小黃鴨時,一邊發呆一邊看著窗外時,一邊睡覺一邊扣肚子時,解決問題的靈感突然就掉進了腦海里。

所以我恬不知恥地將這個 app 發布到了 高效工作 分類,微軟還通過了,現在可以在這裡下載到這個應用:

https://www.microsoft.com/zh-cn/p/loaf-a-winui3-app/9ndj3q12nrrm

當然,如標題所說,這是個 winui 3 app。

2. 什麼是 winui 3

winui 3 是隨 windows app sdk 提供的適用於 windows 桌面應用程式和 uwp 應用程式的本機用戶體驗 (ux) 框架。簡單來說,winui 3 將 uwp 的 ui 層分離出來給 win32 windows app 使用。為了更好地理解 winui 3 可以參考下面的連結:

  1. Windows UI 库 (WinUI) - Windows apps
  2. Windows UI 库 (WinUI) 3 - Windows apps
  3. 通过 Windows 应用 SDK 生成桌面 Windows 应用 - Windows apps
  4. Windows 应用 SDK 的稳定通道发行说明 - Windows apps
  5. microsoftmicrosoft-ui-xaml Windows UI Library_ the latest Windows 10 native controls and Fluent styles for your applications
  6. microsoft-ui-xaml_roadmap
  7. WinUI 3 试玩报告
  8. WinUI 3 Preview 3 发布了,再一次试试它的性能

經過長久的等待,最近,winui 3 好像悄悄地發布了正式版。既沒有大型的宣傳,又沒有集成在剛剛發布的 visual studio 2022 里,甚至沒看到像樣的郵件或新聞、博客,查文檔的話它好像和 windows app sdk 一起發布了,總之現在 winui 3 的 1.0 版本能用了。在把玩了一番後我覺得暫時不能把自己的 app 遷移到 winui 3,雖然我已經期待了很久很久。因為不能對現有應用動手,又為了更深入嘗試 winui 3,我做了“摸魚”這個小應用。

3. 開發過程

下面來說說開發過程。總體來說挺好玩,但也有很多挑戰。

首先,如果要使用 Visual Studio 2022 开发 WinUI 3 的 C# App,需要下载 Visual Studio 2022 的扩展:WindowsAppSDK.Cs.Extension.Dev17.Standalone.vsix。安装扩展后才可以创建 WinUI 3 项目。

c++ 或 visual studio 2019 的擴展可以在以下文檔找到各自的下載連結:

Windows 应用 SDK 的稳定通道发行说明 - Windows apps

創建好項目後就會發現 winui 3 沒有設計視圖(以後應該也不會有),所以這時候最好還是再創建一個 uwp 項目,在 uwp 項目中把 xaml 設計好再複製到 winui 3 項目。

迁移过程中需要将大部分 Windows.* 命名空间替换成 Microsoft.*。不过 Win2D 里还在用 Windows.* 命名空间,所以搞得有些混乱。

然后就是引用各种包,微软自己管理的 UWP 最常用的包大致上都有对应的 WinUI 版本,例如 Microsoft.Toolkit.Uwp.UI 替换为 CommunityToolkit.WinUI.UI,而 Win2D.uwp 替换为 Microsoft.Graphics.Win2D

uwp 大部分開發經驗都可以用在 winui 3 上,在 摸魚 這個小 app 里遇到最大的問題是 window 管理。可能 winui 3 的 window api 還沒想好,導致連修改標題都很麻煩,需要用到好幾行代碼:

namespace SampleApp
{
    /// <summary>
    /// An empty window that can be used on its own or navigated to within a Frame.
    /// </summary>
    public sealed partial class MainWindow : Window
    {
        private AppWindow m_appWindow;

        public MainWindow()
        {
            this.InitializeComponent();
            // Get the AppWindow for our XAML Window
            m_appWindow = GetAppWindowForCurrentWindow();
            if (m_appWindow != null)
            {
                // You now have an AppWindow object and can call its methods to manipulate the window.
                // Just to do something here, let's change the title of the window...
                m_appWindow.Title = "WinUI ❤️ AppWindow";
            }
        }

        private AppWindow GetAppWindowForCurrentWindow()
        {
            IntPtr hWnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
            WindowId myWndId = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(hWnd);
            return AppWindow.GetFromWindowId(myWndId);
        }
   }
}

進入全屏的代碼也和 uwp 不一樣:

///进入全屏
m_appWindow.SetPresenter(AppWindowPresenterKind.FullScreen);
///退出全屏
m_appWindow.SetPresenter(AppWindowPresenterKind.Default);

而且全屏和 UWP 还不一样,没法按 Esc 键退出全屏,也没有了屏幕顶部隐藏的标题栏。所以要自己捕获全局的 Esc 键事件再调用代码退出全屏(至于平板状态怎么退出全屏我就不知道了)。

還有一點,winui 3 和 uwp 的樣式有些不一樣,例如 progressring 的樣式就不是 windows 8 以來那個幾個點轉圈圈的樣式。幸好可以把 uwp 的 style 複製過來,只需簡單修改一下。

虽然开发过程遇到很多问题,对这个小 App 来说还算轻松愉快。有趣的是,当遇到 WinUI 3 没提供想要的 API 的时候可以直接调用 Win32 API 实现需求。更有趣的是,这些 Win32 API 有些有效,有些无效。

所有代碼完成後,最後一步是發布到商店,幸好發布流程和 uwp 的基本一致,現在已經可以在商店下載這款 app。

4. 遇到的問題

沒有設計視圖,這是個很嚴重的問題。我自己倒是還可以接受,因為起碼還有熱重載可用,但對入門不友好。

文档混乱,几乎所有 UWP 和 Windows App SDK 的文档合并了,这就要命了,真的要命,例如 WinUI 3 的文档有指向 Mica 的导航,明明 WinUI 3 都不支持 Mica。现在在 https://docs.microsoft.com/en-us/windows/apps/ 页面里甚至找不到 UWP 的入口,总之无论 UWP 还是 Windows App SDK 的文档都一片混沌。

demo 沒用,給我 uwp 的 demo 就算了,連 windows 8 的 demo 都給我端上來就過分了。

windows app sdk 這個名字本身就不好,所有引擎搜出來一大堆 windows 的東西,但不是 windows app sdk 的。

沒有 background acrylic 和 revealboraderbrush,win2d 也缺了 canvasanimatedcontrol,這些東西的缺失提高了從 uwp 遷移到 winui 3 的難度。

從開發到發布一路上遇上各種一言難盡的 bug 和小問題。

5. 最後

我記得當年 winforms、wpf、silverlight 的入門都相當輕鬆,後面微軟的各個 ui 越來越難,而 winui 3 更是最難的一個。比起 uwp,winui 3 本應該有巨大的優勢,但現在我建議暫時還是再等等新版本。玩玩小應用可以,生產環境要謹慎。

倒是 winui 2 好像越來越好玩,或者我們可以一邊玩 winui 2 一邊等 winui 3 的新版本。

6. 源碼

https://github.com/DinoChan/Loaf

作者:dino.c

出處:https://www.cnblogs.com/dino623/p/developing_an_app_with_winui3.html

版權:本文採用“cc by 4.0”知識共享許可協議進行許可。

Keep Exploring

延伸阅读

更多文章
同分类 / 同标签 2026/2/7

aot使用經驗總結

從項目創建伊始,就應養成良好的習慣,即只要添加了新功能或使用了較新的語法,就及時進行 aot 發布測試。

继续阅读