☰
Ant Design Blazor Segmented 分段控制器禁用(Disabled)完全指南
2026/10/12 1:41:50 网站建设 项目流程
  • 前端
  • UI组件
  • 设计系统

【免费下载链接】ant-design-blazor

基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力,实现更大价值。

项目地址:https://gitcode.com/ant-design-blazor/ant-design-blazor
点击查看免费下载

导读

本文围绕 ant-design-blazor 组件库中 Segmented(分段控制器)的“不可用(Disabled)”用法展开,系统讲解整体禁用、单项禁用与动态切换禁用三种实战场景,并结合仓库源码剖析禁用状态的实现原理与底层样式机制。读完本文,你将掌握如何在 Blazor 项目中通过Disabled参数精确控制 Segmented 的可用状态,并理解其背后的组件联动与交互阻断逻辑。

一、禁用场景一览:从官方 demo 出发

本指南对应仓库中的官方演示文档 disabled.md 及其配套示例 Disabled.razor。原文档的定位是“Segmented 不可用 / Disabled Segmented”,即展示分段控制器在禁用状态下的完整行为。该 demo 一共演示了四种禁用形态,覆盖了 Segmented 所有声明式配置入口:

<Segmented TValue="string" Labels="@(new []{"Map", "Transit", "Satellite"})" Disabled /> <br /> <Segmented TValue="string" Options="@options" /> <br /> <Segmented @bind-Value="_value" Disabled> <SegmentedItem Value="true" Label="True" /> <SegmentedItem Value="false" Label="False" /> </Segmented> <br /> <Segmented @bind-Value="_value" Disabled="_disabled"> <SegmentedItem Value="true" Label="True" /> <SegmentedItem Value="false" Label="False" /> </Segmented> <br /> <Switch @bind-Checked="_disabled" CheckedChildren="Disabled" UnCheckedChildren="Enable"/> @code { bool _disabled; bool _value; SegmentedOption<string>[] options = { new("Daily"), new("Weekly", "Weekly", true), new("Monthly"), new("Quarterly", "Quarterly", true ), new("Yearly"), }; }

场景一:Labels模式整体禁用

<Segmented TValue="string" Labels="@(...)" Disabled />只用一个布尔属性Disabled,即可让整个分段控制器全部选项不可用。这是最直观的整体禁用写法,适合表单提交前后、权限受限、数据未就绪等场景。

场景二:Options模式单项禁用

Options接受SegmentedOption<TValue>数组。每个选项通过构造函数new("Weekly", "Weekly", true)指定三个字段:Value(值)、Label(显示文案)、Disabled(是否禁用)。在上述示例中,Weekly与Quarterly被标记为禁用,而Daily、Monthly、Yearly保持可选,实现了同一分段控制器内部分选项禁用、部分可用的混合状态。

SegmentedOption<TValue>在仓库中的定义非常精简(见 SegmentedOption.cs):

public record struct SegmentedOption<TValue>(TValue Value, string Label = null, bool Disabled = false) { public string Label { get; set; } = Label ?? Value.ToString(); }

可见Label为可选参数,缺省时直接取Value的字符串表示;Disabled默认值为false。

场景三:ChildContent模式下整体禁用

当使用SegmentedItem声明子项时,同样可以在父级Segmented上直接设置Disabled,一次性禁用所有子分段项:

<Segmented @bind-Value="_value" Disabled> <SegmentedItem Value="true" Label="True" /> <SegmentedItem Value="false" Label="False" /> </Segmented>

场景四:动态切换禁用状态

demo 的最后一段把Disabled绑定到可变的_disabled字段,并通过Switch组件控制:

<Segmented @bind-Value="_disabled" ... > @* 示意:Disabled 绑定变量 *@ <Switch @bind-Checked="_disabled" CheckedChildren="Disabled" UnCheckedChildren="Enable"/>

当开关拨动时,Segmented 会在禁用与可用状态间实时切换,无需重建组件。这为“编辑态 / 只读态”切换、权限动态变更等交互提供了开箱即用的支持。

二、API 参数:Disabled的声明方式

根据组件官方 API 文档 index.zh-CN.md,Segmented 的核心参数如下(自v0.12.0版本提供该组件):

参数说明类型默认值
Block将宽度调整为父元素宽度booleanfalse
DefaultValue默认选中的值TValue-
Disabled是否禁用booleanfalse
Labels使用字符串同时作为 Label 和 Valuestring[]-
OnChange选项变化时的回调函数EventCallback<TValue>-
Options数据化配置选项内容TValue[][]
Size控件尺寸large|middle|small-
Value当前选中的值TValue-

其中Disabled存在两级作用域:

  1. 组件级(整体禁用):设置在Segmented<TValue>上,作用于全部选项;
  2. 项级(单项禁用):设置在SegmentedItem<TValue>的Disabled参数上,或通过SegmentedOption<TValue>构造函数的第三个参数指定。

三、源码剖析:禁用状态的实现原理

1. 组件级禁用:状态变更的级联传播

在 Segmented.razor.cs 中,Disabled参数并非简单赋值:

[Parameter] public bool Disabled { get => _disabled; set { if (_disabled == value) return; _disabled = value; _items.ForEach(item => item.MarkStateHasChanged()); } }

当Disabled值发生变化时,组件会遍历内部维护的_items(即所有SegmentedItem)并逐个调用MarkStateHasChanged()触发重渲染,确保禁用样式与交互状态实时同步。这种“父参数变更 → 子项级联刷新”的设计正是场景四动态切换能即时生效的原因。

同时,在OnInitialized中通过ClassMapper挂载根样式类(Segmented.razor.cs):

ClassMapper.Add(PrefixCls) .If($"{PrefixCls}-lg", () => Size == SegmentedSize.Large) .If($"{PrefixCls}-sm", () => Size == SegmentedSize.Small) .If($"{PrefixCls}-disabled", () => Disabled) .If($"{PrefixCls}-block", () => Block) .If($"{PrefixCls}-rtl", () => RTL);

整体禁用时根元素会获得ant-segmented-disabled类,用于承载容器级的禁用视觉反馈。

2. 项级禁用:Disabled的 OR 合并逻辑

在 SegmentedItem.razor.cs 中,单项的禁用状态由自身与父级共同决定:

protected override void OnInitialized() { base.OnInitialized(); ClassMapper.Add(PrefixCls) .If($"{PrefixCls}-selected", () => _selected) .If($"{PrefixCls}-disabled", () => Disabled || Parent?.Disabled == true); Parent?.AddItem(this); }

ant-segmented-item-disabled类在自身 Disabled 或父级 Segmented.Disabled 任一为真时被加上,因此只要有一方禁用,该项即进入禁用态。

交互阻断逻辑同样遵循该 OR 规则(SegmentedItem.razor.cs):

private void OnClick() { if (Disabled || Parent.Disabled) { return; } Parent.Select(this); }

点击事件处理器在禁用条件下直接return,不会触发Parent.Select(this),因此既不会更新选中值,也不会产生选中滑块(thumb)动画。

3. 三种声明入口的渲染汇聚

组件模板 Segmented.razor 按优先级渲染内容:ChildContent>Options>Labels,并依据不同入口合并禁用状态:

  • 走ChildContent(SegmentedItem)时,禁用状态由SegmentedItem.Disabled自身承担;
  • 走Options时,模板写成Disabled="@(option.Disabled || Disabled)",将选项级与组件级禁用合并后传给SegmentedItem;
  • 走Labels时,模板直接传递Disabled="Disabled",即所有由 Label 生成的项共享组件级禁用状态。

SegmentedItem最终渲染为<label class="ant-segmented-item ...">包裹的隐藏 radio 输入(见 SegmentedItem.razor),禁用态下该 label 失去可点击性。

四、样式层:禁用态的视觉呈现

禁用样式定义在 index.less 与 mixins.less 中:

// index.less &-item-disabled { .segmented-disabled-item(); } // mixins.less .segmented-disabled-item { &, &:hover, &:focus { color: @disabled-color; cursor: not-allowed; } }

ant-segmented-item-disabled项在普通、悬浮、聚焦三种状态下均使用@disabled-color(禁用色)显示文字,并将光标改为not-allowed,从视觉上明确告知用户不可交互。此外容器级禁用时,index.less 中的 hover 背景反馈也会被取消:

&:not(&-disabled) { &:hover, &:focus { background-color: @segmented-hover-bg; } }

即整体禁用(ant-segmented-disabled)时,整个控制器不再响应 hover 背景变化,进一步强化禁用语义。

五、测试佐证:渲染行为的可验证性

仓库在 SegmentedTests.razor 中提供了组件渲染测试,可验证选中项结构与 radio 输入渲染:

var cut = Context.Render(@<Segmented Labels=@(new[]{"Daily", "Weekly"}) />); cut.MarkupMatches( @<div class=" ant-segmented" id:ignore> <div class="ant-segmented-group"> <label class=" ant-segmented-item ant-segmented-item-selected" id:ignore> <input class="ant-segmented-item-input" type="radio" checked=""> ...

结合前文源码可以看出:每个分段项对应一个ant-segmented-item标签与一个隐藏 radio 输入,选中项额外获得ant-segmented-item-selected类。禁用项在此基础上会追加ant-segmented-item-disabled类,并受OnClick逻辑保护,这正是编写组件级测试时可用于断言的关键标记。

六、实践要点与注意事项

  1. 两种粒度按需选择:若整个控制器都不允许操作,优先在Segmented上设置Disabled;若仅部分选项不可用,则通过Options中SegmentedOption的Disabled或SegmentedItem的Disabled逐项声明。
  2. 禁用不影响已选值:Disabled只阻断新的点击交互,不会清空当前的Value,已选中项在禁用态下仍保持高亮(ant-segmented-item-selected)。
  3. 动态切换成本极低:由于父级Disabled的 setter 会级联触发所有子项MarkStateHasChanged(),配合Switch等控件进行只读/编辑态切换时无需手动重建选项。
  4. 权限与表单场景结合:可将Disabled绑定到权限判断、表单校验结果或异步加载状态,实现数据未就绪前的占位锁定。
  5. 视觉与语义一致性:禁用态的最终观感由@disabled-color主题变量控制,如需全局调整,可在 variable.less 中定制该变量,而无需改动组件代码。

本文所涉代码与文档均可在仓库对应路径直接查看:demo 元数据、demo 实现、组件实现、样式定义 与 API 文档。

  • 前端
  • UI组件
  • 设计系统

【免费下载链接】ant-design-blazor

基于 Ant Design 与 Blazor 的前端组件库。让开发者解放生产力,实现更大价值。

项目地址:https://gitcode.com/ant-design-blazor/ant-design-blazor
点击查看免费下载
上一篇:Chat LangChain 完整教程:三步搭建一个 LangChain 文档问答助手
下一篇:WPF UI NavigationView 完整上手指南:10 分钟搭好应用导航

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询