Skip to content

Reactor

Microsoft.UI.Reactor(以下简称 Reactor)是一个声明式 UI 框架,用于以纯 C# 构建原生 Windows 桌面应用。没有 XAML,没有数据绑定,没有视图模型。你把 UI 描述成状态的函数,Reactor 负责让屏幕与状态保持同步。

如果你想…… 从这里开始
构建第一个 Reactor 应用 快速上手
理解思维模型 Reactor 思维模型
移植 XAML/WinUI/WPF 应用 面向 XAML 开发者的 Reactor
查阅某个 Hook 或修饰符 API 参考
了解运行时的工作原理 架构概览

为什么选择 Reactor?

自上而下纯 C#。 你的整个应用——布局、样式、状态、逻辑——都写在 .cs 文件里。没有标记语言,没有 code-behind 的分离,也没有设计器生成文件。

声明式渲染。 你编写一个返回 UI 的 Render() 方法。当状态发生变化时,Reactor 对新旧元素树做差异比对,只把变化的部分打补丁到原生 WinUI 控件上。

用 Hook 管理状态。 UseStateUseReducerUseEffect 等一系列 Hook 为你带来 React 风格的状态管理,却不需要写一行 JavaScript。

原生性能。 Reactor 渲染出的是真正的 WinUI 3 控件。你的应用就是一个标准的 Windows 桌面应用——不内嵌 WebView,不用 Electron,没有解释层。

快速一览

一个完整的 Reactor 应用,全部写在一个文件里:

class HelloWorld : Component
{
    public override Element Render()
    {
        return VStack(12,
            TextBlock("Hello from Reactor!").FontSize(24).Bold(),
            TextBlock("No XAML. No data binding. Just C#.")
        ).Padding(24);
    }
}

Hello world component

几行代码搞定状态与交互:

class QuickCounter : Component
{
    public override Element Render()
    {
        var (count, setCount) = UseState(0);

        return HStack(8,
            Button("- 1", () => setCount(count - 1)),
            TextBlock($"{count}").FontSize(20).SemiBold().Width(40)
                .HAlign(HorizontalAlignment.Center),
            Button("+ 1", () => setCount(count + 1))
        ).Padding(24);
    }
}

Counter demo

内置的文本样式:

class StyledText : Component
{
    public override Element Render()
    {
        return VStack(8,
            Heading("Heading element"),
            SubHeading("SubHeading element"),
            TextBlock("Regular text with modifiers")
                .FontSize(14).Foreground(Theme.Accent),
            Caption("Caption for fine print")
        ).Padding(24);
    }
}

Styled text elements

工作原理

  1. 定义组件——带有 Render() 方法、返回元素树的类。
  2. Hook 管理状态——UseStateUseReducerUseEffect 等等,都在 Render() 内部调用。
  3. 状态变化时,Reactor 重新调用 Render(),对结果做差异比对,只更新那些真正发生变化的 WinUI 控件。

就是这么简单。没有需要自己管理的事件订阅,没有需要接线的属性变更通知,也没有需要操心的调度线程问题。

文档

本套文档分为十节,从"让第一个应用出现在屏幕上"一路讲到"运行时是怎么造出来的"。XAML 开发者建议先读第 1、8、9 节,其他读者按章节顺序阅读即可。

1. 快速上手

2. 学习框架

3. UI 呈现

  • 布局 — VStack、HStack、Grid、ScrollView、Border,以及响应式模式
  • 弹性布局(Flex Layout) — 面向自适应 UI 的 flex 盒式布局
  • 样式与主题 — 颜色、字体排版、深色/浅色主题、自定义样式
  • 动画 — 过渡、关键帧、交互状态、动画编排
  • 输入与手势 — 指针事件、点击、手势、访问键

4. 控件目录

  • 控件 — 带缩略图索引的全量控件目录
  • 表单与输入 — 文本框、复选框、滑块、校验、数据录入
  • 集合 — 面向大数据集的 ListView、LazyVStack、VirtualList
  • 文本与媒体 — TextBlock、MarkdownTextBlock、Image、MediaPlayerElement、WebView2、InkCanvas
  • 状态与信息 — InfoBar、InfoBadge、ProgressBar、TeachingTip、PipsPager
  • 对话框与浮出层 — ContentDialog、MenuFlyout、CommandBarFlyout、Popup
  • 数据系统 — 支持排序、筛选、搜索与行内编辑的 DataGrid
  • 图表 — 使用 ReactorCharting 库绘制折线图、柱状图、面积图、饼图
  • Win2D 画布 — 来自可选包 Microsoft.UI.Reactor.Advanced 的即时模式绘图表面(手动、动画、虚拟三种)

5. 应用架构

  • 导航 — NavigationView、TabView、多页面应用、路由
  • 窗口 — 顶层窗口、托盘图标、跳转列表、OpenWindow、关闭策略
  • 高级窗口特性 — 分层叠加层、窗口区域,以及其他重度依赖互操作的范例
  • 停靠窗口 — 可重排的停靠面板:拆分、标签页、侧边固定、浮动拖出、布局持久化
  • 异步资源UseResourceUseInfiniteResourceUseMutationPending
  • 持久化UsePersisted、作用域、迁移
  • 本地化 — 多语言支持、资源字符串、RTL(从右向左)布局
  • 无障碍 — 屏幕阅读器、键盘导航、焦点捕获、运行时扫描

6. 模式与实践范例

  • 实践范例 — 端到端模式合集(登录、主从视图、分页列表、命令面板……)
  • 速查表 — 单页速查卡片
  • Reactor 准则 — Hook 规则、渲染纯度、反面模式
  • 主题令牌 — 附色板的完整令牌目录

7. 工具与流程

  • 开发工具mur CLI、MCP 服务器、VS Code 面板、dotnet watch、应用内开发菜单
  • Visual Studio 扩展 — 面向 Visual Studio 2022 (17.8+) 与 2026 (18.x) 的粗略实验性内嵌预览
  • 测试 — 无头渲染器、结构断言、异步测试模式
  • 性能 — ETW、EventDispatch、火焰图
  • 打包 — MSIX、单文件、ARM64、AOT 相关考量

8. 互操作与集成

(XAML 迁移内容放在第 1 节——XAML 开发者是主要入口路径之一。)

9. 底层原理

运行时解析——写给那些不满足于"怎么用"、还想知道它为什么是这样设计的读者。

10. API 参考

src/Reactor*/ 中的 XML 文档注释自动生成。每个成员都有一套统一的页面结构:摘要 / 参数 / 返回值 / 说明 / 示例 / 另请参阅。

  • Hook — 每一个 Use* Hook
  • 工厂(Factories) — 每一个元素工厂(即将推出)
  • 修饰符(Modifiers) — 每一个可链式调用的修饰符(即将推出)
  • 元素(Elements) — 每一种元素记录类型(即将推出)
  • 系统(System) — App、Window、Navigation、Context、Command(即将推出)

最小项目配置

最快的路径是 dotnet new reactorapp,它会替你搭好下面这一切。若想手动配置,则创建一个控制台项目并编辑 .csproj

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>WinExe</OutputType>
    <TargetFramework>net10.0-windows10.0.22621.0</TargetFramework>
    <UseWinUI>true</UseWinUI>
    <WindowsPackageType>None</WindowsPackageType>
    <!-- Windows App SDK needs a concrete architecture; without this an
         unqualified `dotnet build` / `dotnet run` fails with
         "WindowsAppSDKSelfContained requires a supported Windows architecture". -->
    <RuntimeIdentifier Condition="'$(RuntimeIdentifier)' == '' And ('$(Platform)' == '' Or '$(Platform)' == 'AnyCPU')">$(NETCoreSdkPortableRuntimeIdentifier)</RuntimeIdentifier>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.UI.Reactor" Version="0.1.0-preview.15" />
  </ItemGroup>
</Project>

只需一个包引用就够了——Microsoft.UI.Reactor 会以传递依赖的方式引入 Windows 应用 SDK,所以只有在你想锁定某个特定的 WinUI 补丁版本,或想通过 WindowsAppSDKSelfContained 把运行时一起打包时,才需要自己添加 Microsoft.WindowsAppSDK。项目模板使用的 <Platforms>、ARM64 与自包含形态,参见打包

App.cs 换成一个组件加一次 ReactorApp.Run<T>() 调用,然后 dotnet run——你的第一个 Reactor 应用就跑起来了。

小贴士

从函数组件开始。 如果只是想快速试验,可以用 ReactorApp.Run("Title", ctx => { ... })——连类都不用定义。

读一读 Hook 那一页。 Hook 是 Reactor 的核心。理解了 UseStateUseEffect,其余一切都迎刃而解。

保持组件短小。 尽早把局部内容抽成独立组件。由组合构成的结构,永远比一个巨大的 Render() 更容易推理。

下一步

  • 快速上手 — 构建第一个应用、管理状态、完成一个待办清单。
  • HookUseStateUseEffectUseMemo,以及其他核心状态原语。
  • 组件 — 组件类、props 与函数组件详解。
  • 面向 XAML 开发者的 Reactor — XAML、绑定、MVVM 与导航的迁移手册。