控件¶
class ControlsCatalogApp : Component
{
public override Element Render() => VStack(8,
TextBlock("Controls catalog").FontSize(20).Bold(),
TextBlock("Every Reactor control, grouped by category.").Opacity(0.7),
Button("Open Forms", () => { })
).Padding(16);
}
屏幕上一切可见之物都是控件。在 Microsoft.UI.Reactor(Reactor)中,控件就是 TextBlock(...)、Button(...) 这类工厂方法的返回值 —— 一个普通元素,你可以组合它、往它上面串修饰符、然后从 Render() 返回。下面十个分类覆盖了 Reactor 当前暴露的全部控件。挑一个分类、打开它的详情页,里面能找到该分类下每个控件的工厂签名、修饰符矩阵和截图。
整个目录有两条基本规则:
- 每个控件都有 Reactor 工厂方法。
Render()里不写 XAML ——Microsoft.UI.Reactor.Factories上的工厂方法就是组合 UI 所需要的全部东西。 - WinUI 包装控件只做外链,不重复文档。 当某个控件(如
DatePicker、AutoSuggestBox)只是一层透明的 WinUI 包装时,Reactor 页面只覆盖工厂与修饰符表面,然后链到 Microsoft Learn 的设计页去讲主题、布局建议和无障碍行为。Reactor 原创控件(DataGrid、Markdown、VirtualList、FlexPanel)则在各自的页面里详尽成文。
What "every control" means here, precisely. The tables below are the
mountable control catalog: every element type registered with the
ControlRegistry by
ReactorApp.RegisterAllBuiltIns(),
minus nine framework elements that are plumbing rather than something you
pick off a shelf. CommandHost and NavigationHost are wiring emitted by
commanding and navigation; FormField,
ValidationRule, and ValidationVisualizer are the
forms validation decorators; Semantic is the
accessibility annotation wrapper; XamlHost and
XamlPage are the XAML interop hosts; and
AnnounceRegion is internal — it exists only to back the
UseAnnounce hook and has no public factory. A unit
test (ControlCatalogCompletenessTests) fails the build when a newly
registered control is missing from this page, so the claim above is
checked rather than asserted.
分类¶
| 分类 | 包含内容 | 详情页 |
|---|---|---|
| 表单 | 文本输入、选择器、按钮、校验基元 | 表单 |
| 集合 | 列表、网格、虚拟化列表、中继器 | 集合 |
| 文本与媒体 | 标题、富文本、图像、媒体播放器 | 文本与媒体 |
| 状态与信息 | 进度、信息栏、徽标、教学提示 | 状态与信息 |
| 布局与容器 | 栈、网格、边框、滚动宿主、窗格 | 布局 |
| 导航 | 导航视图、框架、选项卡、面包屑、枢轴 | 导航 |
| 形状与图标 | 矩形、椭圆、线段、路径、图标源 | 样式 |
| 对话框与浮出 | 内容对话框、菜单浮出、命令栏浮出 | 对话框与浮出 |
| 数据系统 | DataGrid、列、数据源、分页 | 数据系统 |
| 图表 | 折线、条形、面积、饼图、力导向图 | 图表 |
表单¶
文本输入、选择、滑块、按钮以及校验管线。表单是大多数应用停留时间最长的分类;详情页(forms.md)覆盖了受控输入模式和 FormField 校验表面。
class FormsGroup : Component
{
public override Element Render()
{
var (name, setName) = UseState("Ada");
var (agree, setAgree) = UseState(true);
var (volume, setVolume) = UseState(60.0);
return VStack(8,
TextBox(name, setName, placeholderText: "Name", header: "Name").Width(200),
CheckBox(agree, setAgree, label: "I agree"),
Slider(volume, 0, 100, setVolume).Width(200),
Button("Submit", () => { })
).Padding(16);
}
}
![]()
| 控件 | 说明 |
|---|---|
TextBox |
单行文本输入,带占位符与标题头。 |
PasswordBox |
遮蔽显示的文本输入。 |
NumberBox |
带上下微调按钮的数字输入。 |
AutoSuggestBox |
带筛选建议列表的文本输入。 |
CheckBox / ThreeStateCheckBox |
两态或三态复选框,可带标签。 |
ToggleSwitch |
两态开关,可带标题头。 |
Slider |
有最小/最大值边界的数值。 |
ComboBox |
字符串下拉列表。 |
RadioButtons |
单选按钮组。 |
RadioButton |
单个单选按钮,用于手工搭建分组。 |
DatePicker |
内联的三栏滚选日期选择器(非空)。 |
CalendarDatePicker |
紧凑按钮,点开弹出日历(可为空)。 |
CalendarView |
完整月视图网格,支持单选 / 多选 / 区间选择。 |
TimePicker |
时 / 分 / 时段滚选器。 |
ColorPicker |
连续取色,含色谱与十六进制输入。 |
Button |
带标签的点击处理器。 |
RepeatButton |
按住期间连续触发。 |
ToggleButton / ThreeStateToggleButton |
能锁存状态的按钮。 |
HyperlinkButton |
链接样式按钮,带导航目标。 |
DropDownButton |
打开附着浮出层的按钮。 |
SplitButton / ToggleSplitButton |
主动作加一个下拉半区。 |
WinUI 设计页:Buttons、 Text controls。
集合¶
绑定列表的渲染与虚拟化。当数据能装进内存、且行模板统一时用 ListView;当列表大到全部挂载会拖累帧耗时,用 VirtualList;当布局必须是栈、但挂载成本成为瓶颈时,用 LazyVStack。
class CollectionsGroup : Component
{
public override Element Render()
{
var items = new[] { "Alpha", "Bravo", "Charlie", "Delta" };
return VStack(4,
TextBlock("Items").Bold(),
ForEach(items, item => TextBlock($" • {item}").WithKey(item))
).Padding(16);
}
}
![]()
| 控件 | 说明 |
|---|---|
ListView<T> |
带键的绑定列表,每项有独立的视图构造器。 |
GridView<T> |
平铺式绑定集合。 |
ListBox |
紧凑的非虚拟化选择列表。 |
LazyVStack<T> / LazyHStack<T> |
延迟挂载的纵向 / 横向栈。 |
VirtualList |
索引驱动的虚拟列表,带滚动 API。 |
ItemsRepeater<T> |
裸虚拟化面板 —— 无装饰、无选择。 |
ItemsView<T> |
现代项宿主,带类型化选择。 |
ItemContainer |
为手工搭建的项宿主提供选择 / 悬停装饰。 |
TreeView<T> |
层级列表,支持展开 / 折叠。 |
ForEach |
不用列表控件也能组合出元素序列。 |
详情页:集合。
文本与媒体¶
只读的展示表面:标题、正文、富格式文本、图像、视频。其中大多是透明的 WinUI 包装;这里的 Reactor 原创控件是 Markdown(string),它渲染 Markdown 而无需绕道 WebView。
class TextAndMediaGroup : Component
{
public override Element Render() => VStack(6,
TextBlock("Heading").FontSize(20).Bold(),
TextBlock("Body text with a moderately long paragraph " +
"for catalog-thumb composition.").Opacity(0.8)
).Padding(16);
}
![]()
| 控件 | 说明 |
|---|---|
TextBlock |
单行或自动换行的文本。 |
Title / Heading / SubHeading / Subtitle |
语义化标题字号。 |
Body / BodyLarge / BodyStrong / Caption |
语义化正文与元信息字号。 |
RichTextBlock |
内联格式化的文本。 |
RichEditBox |
可编辑的富文本。 |
Markdown |
Reactor 原创 Markdown 渲染器(Microsoft.UI.Reactor.Advanced)。 |
Image |
位图源。 |
MediaPlayerElement |
视频 / 音频播放。 |
WebView2 |
嵌入式 Chromium 表面。 |
MapControl |
由 Bing 地图支撑的地图表面。 |
InkCanvas |
手写笔输入。未包装 —— 参见差距分析。 |
详情页:文本与媒体。
状态与信息¶
非交互式的反馈:进度、徽标、信息栏、教学提示。用它们来告知而不抢焦点 —— 需要阻断式确认时,应该改用对话框与浮出。
class StatusGroup : Component
{
public override Element Render() => VStack(8,
TextBlock("Saving…").Bold(),
TextBlock("3 of 12 items").Opacity(0.7)
).Padding(16);
}
![]()
| 控件 | 说明 |
|---|---|
Progress / ProgressIndeterminate |
线性的确定 / 不确定进度条。 |
ProgressRing |
表示不确定工作的转圈指示器。 |
InfoBar |
内联的应用状态消息。 |
InfoBadge |
通知计数徽标。 |
TeachingTip |
一次性引导气泡。 |
PipsPager |
紧凑的分页圆点。 |
PersonPicture |
联系人头像。 |
RatingControl |
0–5 星评分。 |
详情页:状态与信息。
布局与容器¶
负责给子元素定位的面板,以及为单个子元素添加装饰、滚动或裁剪的宿主。这是目录里的结构那一半 —— 它们很少单独出现,但每个界面都由它们构成。
class LayoutGroup : Component
{
public override Element Render() => VStack(8,
Card(
HStack(8,
TextBlock("Border / Card").Bold(),
TextBlock("wraps one child").Opacity(0.7)
).Padding(8)
),
Expander("Expander", TextBlock("Collapsible section body.")),
Viewbox(TextBlock("Viewbox scales its child").FontSize(10))
).Padding(16);
}
![]()
| 控件 | 说明 |
|---|---|
VStack / HStack |
带间距的线性栈 —— 默认面板。 |
Grid / UniformGrid / InterspersedGrid |
行 / 列网格布局。 |
FlexRow / FlexColumn |
经 Yoga 实现的 CSS Flexbox 布局(flex-layout)。 |
WrapGrid |
项依次排布并换行。 |
RelativePanel |
基于约束的兄弟元素定位。 |
Canvas |
绝对 X/Y 定位。 |
Border / Card |
单子元素装饰:背景、圆角、描边。 |
Viewbox |
等比缩放单个子元素以适应空间。 |
ScrollView / ScrollViewer |
滚动宿主(现代 / 经典)。 |
AnnotatedScrollBar |
带标签刻度的滚动条。 |
SplitView |
可折叠侧边窗格加内容区。 |
Expander |
可折叠的标题头 + 内容区块。 |
RefreshContainer |
下拉刷新包装器。 |
SwipeControl |
在项上滑动唤出命令。 |
SemanticZoom |
成对的放大 / 缩小视图。 |
ParallaxView |
以偏移速率滚动的背景。 |
导航¶
在界面或分区之间移动用户的控件。把它们和 navigation.md 上的路由 Hook 配对使用 —— 控件是外壳,导航状态是 Hook。
class NavigationGroup : Component
{
public override Element Render()
{
var (tab, setTab) = UseState(1);
return VStack(8,
BreadcrumbBar([
new BreadcrumbBarItemData("Home"),
new BreadcrumbBarItemData("Controls"),
]),
SelectorBar([
new SelectorBarItemData("All"),
new SelectorBarItemData("Forms"),
new SelectorBarItemData("Layout"),
], tab, setTab)
).Padding(16);
}
}
![]()
| 控件 | 说明 |
|---|---|
NavigationView |
顶部或左侧的应用导航外壳。 |
Frame |
带返回栈集成的页面宿主。 |
BreadcrumbBar |
祖先路径,可点击跳转。 |
TabView |
可关闭、可重排的文档选项卡。 |
Pivot |
可滑动的顶层分区切换器。 |
SelectorBar |
紧凑的内联分段选择器。 |
FlipView |
一次一项的分页视图。 |
TitleBar |
自定义窗口标题栏内容。 |
形状与图标¶
矢量基元与图标源。形状的 Fill / Stroke 接受 Brush(而不是面板级 .Background(...) 接受的颜色字符串)。需要命令式 2D 绘制,参见 Win2D canvas。
class ShapesGroup : Component
{
// Shape fills/strokes take a WinUI Brush (not a color string like the
// panel-level .Background(string) modifier).
static SolidColorBrush Swatch(byte r, byte g, byte b) =>
new(Color.FromArgb(255, r, g, b));
public override Element Render() => HStack(12,
Rectangle().Width(48).Height(32).Fill(Swatch(0x4a, 0x7e, 0xbb)),
Ellipse().Width(40).Height(40).Fill(Swatch(0xbb, 0x4a, 0x7e)),
Line(0, 0, 48, 32).Stroke(Swatch(0x7e, 0xbb, 0x4a)).StrokeThickness(3)
).Padding(16);
}
![]()
| 控件 | 说明 |
|---|---|
Rectangle |
矩形,可带圆角。 |
Ellipse |
椭圆 / 圆。 |
Line |
两点之间的直线段。 |
Path2D |
由路径数据描述的任意几何图形。 |
Icon |
多态图标源(字体字形、符号、位图、路径)。 |
AnimatedIcon |
能在状态间播放过渡的图标。 |
AnimatedVisualPlayer |
Lottie / 合成动画宿主。 |
对话框与浮出¶
模态和临时性的表面。Reactor 通过命令系统把它们接起来,因此同一个 Command<T> 能同时点亮一个按钮、一个菜单项和一个键盘快捷键,而不必复制逻辑。
class DialogsGroup : Component
{
public override Element Render() => VStack(8,
TextBlock("Confirm action").Bold(),
TextBlock("This cannot be undone.").Opacity(0.8),
HStack(8,
Button("Cancel", () => { }),
Button("Delete", () => { })
)
).Padding(16);
}
![]()
| 控件 | 说明 |
|---|---|
ContentDialog |
模态的全屏确认框。 |
Flyout |
锚定的轻量表面,可放任意内容。 |
MenuFlyout |
附着于目标元素的上下文菜单。 |
CommandBarFlyout |
带命令的迷你工具栏。 |
CommandBar |
常驻的主 / 次命令条。 |
MenuBar |
经典顶层菜单栏。 |
Popup |
自由形态的锚定表面。 |
详情页:对话框与浮出。
数据系统¶
DataGrid 以及数据源 / 列 / 分页基元。数据系统的表面是 Reactor 原创的(WinUI 中没有对应物),在 data-system.md 中有详尽文档。
class DataSystemGroup : Component
{
public override Element Render()
{
var rows = new[] { ("Ada", 36), ("Linus", 55), ("Grace", 85) };
return VStack(4,
HStack(16,
TextBlock("Name").Bold(),
TextBlock("Age").Bold()
),
ForEach(rows, r => HStack(16,
TextBlock(r.Item1),
TextBlock(r.Item2.ToString())
).WithKey(r.Item1))
).Padding(16);
}
}
![]()
| 控件 / 类型 | 说明 |
|---|---|
DataGrid<T> |
虚拟化网格,支持排序 / 筛选 / 行内编辑。 |
Column<T> |
列描述符 + 构造器。 |
IDataSource<T> |
可插拔的数据源抽象。 |
ListDataSource<T> |
内存数据源,带客户端排序/筛选。 |
DataPageCache<T> |
增量分页缓存。 |
详情页:数据系统。
图表¶
ReactorCharting 包 —— 像其他元素一样可组合的图表基元。用 using static Microsoft.UI.Reactor.Charting.Charts; 把图表引入作用域。
class ChartingGroup : Component
{
public override Element Render() => VStack(8,
TextBlock("Revenue (Q1–Q4)").Bold(),
// Placeholder visual — the real charting category uses ReactorCharting.
TextBlock("▁ ▃ ▅ ▇").FontSize(28)
).Padding(16);
}
![]()
| 控件 | 说明 |
|---|---|
LineChart<T> |
带坐标轴的折线系列。 |
BarChart<T> |
条形 / 柱状系列。 |
AreaChart<T> |
折线下方的填充面积。 |
PieChart<T> |
分类占比。 |
TreeChart<T> |
层级布局。 |
ForceGraph |
力导向节点图。 |
详情页:图表。
提示¶
查过目录之前,别急着写自定义 Component。 大多数需求靠组合现有工厂方法就能满足 —— 一张"卡片"就是 Border 里放一个 VStack,一个"统计磁贴"就是两个 TextBlock 叠起来。自定义 Component 的代价,是要永久维护它的 render 函数。
Reactor 原创还是 WinUI 包装,决定了文档在哪儿。 包装控件把设计建议指向 Microsoft Learn;Reactor 原创控件则在这里拥有完整的表面。当单个控件的页面缺了诸如"无障碍行为"这类小节时,先确认它是不是包装控件 —— 答案通常在上游。
目录缩略图不是微型教程。 它们只展示控件在代表性状态下的样子,仅此而已。用法、修饰符和"不要这样做"的反例都在详情页里。