WinUI 3 在 Windows 应用版图中的位置
Windows 上的界面框架有几条并行的技术路线:WPF 成熟稳定、生态庞大;UWP 强调沙盒与触屏,但受限于应用容器;WinUI 3 则是新一代原生控件库,它把整套控件与样式从系统中解耦出来独立发布,因此可以随应用一起升级,不受用户系统版本的限制。
选框架的本质是在选约束:你要沙盒与商店分发,还是要完整的系统访问权限,这决定了技术栈,而不是反过来。
- WinUI 3现代控件与 Fluent 视觉,支持打包与非打包两种分发方式。
- WPF成熟稳定、第三方控件生态最丰富,适合存量企业应用。
- WinForms上手最快,适合内部工具与快速交付的小程序。
工程结构与窗口生命周期
WinUI 3 应用从 Application 派生类开始,在启动回调里创建并激活主窗口。窗口是独立的对象,与页面分离:窗口承载标题栏与系统交互,页面负责内容与导航。这种分离让同一个页面可以放进不同窗口,也让多窗口场景的组织更自然。
public partial class App : Application
{
private Window? _window;
public App() => InitializeComponent();
protected override void OnLaunched(LaunchActivatedEventArgs args)
{
_window = new MainWindow();
_window.Activate();
}
}
注意窗口对象必须被字段持有。Window 是引用类型,如果只写成局部变量,垃圾回收后窗口可能被意外释放,表现为界面消失或行为异常——这是新手最常见的一类问题,也是最容易被忽略的一处细节。
XAML 布局与自适应
XAML 的布局容器分三类:StackPanel 按方向顺序堆叠,Grid 用行列精确定位,RelativePanel 按相对关系描述位置。桌面窗口可以被任意缩放,因此布局要以「比例与最小尺寸」为核心,用星号列宽分配剩余空间,配合 VisualStateManager 在窄窗口下切换为纵向排列。
<Grid ColumnSpacing="16">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="240" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ListView Grid.Column="0" ItemsSource="{x:Bind Vm.Groups}" />
<ScrollViewer Grid.Column="1">
<TextBlock Text="{x:Bind Vm.Detail}" TextWrapping="Wrap" />
</ScrollViewer>
</Grid>
Width="*" 表示占据剩余空间,这是自适应布局的基础写法。相反,把两列都写成固定像素并加上大量外边距去凑位置,一旦用户把窗口拉宽就会出现大片空白,或者内容被裁切。
样式、主题与 Fluent 设计语言
WinUI 3 内置浅色与深色两套资源字典,控件会自动跟随系统主题。自定义颜色时优先引用主题资源而不是硬编码色值,这样在切换主题时界面不会出现「半黑半白」的割裂感。圆角、阴影与材质通过主题资源统一控制,手动改写会让应用显得与系统脱节。
- 主题资源用
ThemeResource引用颜色与画笔,不要写死色值。 - 间距体系统一使用 4 的倍数,控件间距保持一致节奏。
- 动效克制过渡动画服务于状态变化的可理解性,而不是装饰。
- 无障碍为图标按钮补充自动化名称,保证屏幕阅读器可读。
另外要为键盘与高对比度模式做适配:所有可点击元素都要有明确的焦点视觉,配色不能只靠颜色区分状态,还要有形状或文字上的区分,否则色觉障碍用户无法分辨。
数据绑定与列表虚拟化
WinUI 3 支持两种绑定方式:Binding 走运行时反射,灵活但性能一般;x:Bind 在编译期生成代码,速度快、错误能在编译时发现,新项目应当优先使用它。数据源要实现变更通知,界面才会跟随刷新——集合用可观察类型,单个属性则实现属性变更通知接口。
列表性能的关键是虚拟化:控件默认只为可视区域创建容器,滚动时复用。要保住这个特性,就避免把列表放进无限高度的容器里,否则虚拟化失效,一次性创建上千个元素,滚动会明显卡顿。分页加载与增量填充也是长列表的常规手段,配合滚动到底部的加载提示,体验会顺畅很多。
打包分发与常见问题
WinUI 3 支持打包与非打包两种分发。打包应用使用 MSIX,安装卸载干净、支持商店与自动更新,但运行在应用容器中,对文件系统与注册表的访问受限;非打包应用拥有完整权限,适合需要深度集成系统能力的工具,代价是安装包需要自行处理依赖与更新逻辑。
常见问题集中在几处:其一,非打包应用需要自行为运行时部署对应的运行库,否则在未安装框架的机器上无法启动;其二,窗口标题栏自定义后要处理拖拽区域与系统按钮的绘制,遗漏会表现为窗口拖不动;其三,高 DPI 屏幕下要给位图资源准备多倍率版本,否则界面发虚。
<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10">
<Identity Name="JiYun.CodeStack" Version="1.0.0.0"
Publisher="CN=JiYun" />
<Properties>
<DisplayName>吉极云码工具箱</DisplayName>
<PublisherDisplayName>吉极云码</PublisherDisplayName>
</Properties>
</Package>
打包清单里的标识与发布者信息一旦提交就不宜再改,商店会把它作为应用身份的依据;版本号则遵循四段式规则,每次提交必须递增,这点在自动化流水线里要写成校验,避免人工疏忽导致提交失败。
小结与延伸阅读
WinUI 3 的三个关键词是:控件与系统解耦、布局以比例为核心、绑定优先用编译期方案。
- 更成熟的桌面方案,见《WPF 桌面应用实战:MVVM 架构》。
- 底层语言与运行时,读《C# 语言核心:.NET 开发基石》与《.NET 8 新特性与应用开发》。
- 部署与自动化脚本,读《PowerShell 自动化脚本实战》。