WinUI 3 在 Windows 应用版图中的位置

Windows 上的界面框架有几条并行的技术路线:WPF 成熟稳定、生态庞大;UWP 强调沙盒与触屏,但受限于应用容器;WinUI 3 则是新一代原生控件库,它把整套控件与样式从系统中解耦出来独立发布,因此可以随应用一起升级,不受用户系统版本的限制。

选框架的本质是在选约束:你要沙盒与商店分发,还是要完整的系统访问权限,这决定了技术栈,而不是反过来。
技术路线对比
  • WinUI 3现代控件与 Fluent 视觉,支持打包与非打包两种分发方式。
  • WPF成熟稳定、第三方控件生态最丰富,适合存量企业应用。
  • WinForms上手最快,适合内部工具与快速交付的小程序。
WinUI 3 配图:半透明亚克力质感的圆角应用窗口与折叠卡片
亚克力与圆角是 Fluent 语言的视觉锚点,也是 WinUI 的默认质感。

工程结构与窗口生命周期

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 在编译期生成代码,速度快、错误能在编译时发现,新项目应当优先使用它。数据源要实现变更通知,界面才会跟随刷新——集合用可观察类型,单个属性则实现属性变更通知接口。

列表性能的关键是虚拟化:控件默认只为可视区域创建容器,滚动时复用。要保住这个特性,就避免把列表放进无限高度的容器里,否则虚拟化失效,一次性创建上千个元素,滚动会明显卡顿。分页加载与增量填充也是长列表的常规手段,配合滚动到底部的加载提示,体验会顺畅很多。