# Select 使用文档 本文档介绍 AtomUI Select 控件的各种使用方式,示例代码摘自 Gallery 演示程序。 > 📖 Gallery 源码位置:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` --- ## 前置准备 在 AXAML 中使用 Select,需要引入以下命名空间: ```xml xmlns:atom="https://atomui.net" xmlns:antdicons="https://atomui.net/icons/antdesign" ``` 在 C# 代码中引入: ```csharp using AtomUI.Desktop.Controls; // Select, SelectOption, ISelectOption using AtomUI.Controls; // SizeType, InputControlStyleVariant 等共享类型 ``` --- ## 1. 基本用法 最基本的 Select 用法——单选模式,声明式定义选项: ```xml ``` **说明**: - `Header` 是显示文本,`Content` 是选项的值 - `DefaultValues` 通过 `Content` 值匹配来设置默认选中项 - `IsEnabled="False"` 可禁用单个选项 ### 禁用整个 Select ```xml ``` ### 允许清空 ```xml ``` --- ## 2. 搜索过滤 通过 `IsFilterEnabled="True"` 启用展开时的搜索过滤: ```xml ``` **默认行为**:按 `Header` 属性进行模糊匹配。 ### 自定义搜索过滤 使用内置过滤器或自定义 `IValueFilter` 实现: ```xml ``` 在 code-behind 中设置自定义过滤器: ```csharp public class CustomFilter : IValueFilter { public bool Filter(object? value, object? filterValue) { if (value is string valueStr && filterValue is string filterValueStr) { // 区分大小写的包含匹配 return valueStr.Contains(filterValueStr, StringComparison.Ordinal); } return false; } } // 在构造函数或初始化中设置 CustomSearchSelect.Filter = new CustomFilter(); ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Custom Search" 示例。 --- ## 3. 多选模式 通过 `Mode="Multiple"` 启用多选,已选项以标签形式展示: ```xml ``` **说明**: - 多选模式下,`DefaultValues` 支持逗号分隔的多个值 - 每个已选项显示为可关闭的标签(Tag) - 点击标签上的关闭按钮可取消选中 - `Backspace` / `Delete` 键可删除最后一个标签 ### 禁用多选 Select ```xml ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "multiple selection" 示例。 --- ## 4. 标签模式(Tags) 通过 `Mode="Tags"` 允许用户从列表选择或自由输入创建新标签: ```xml ``` **Tags 模式特殊行为**: - 搜索功能自动启用(即使 `IsFilterEnabled="False"`) - 当输入内容无匹配项时,自动创建一个新的临时选项 - 选中后临时选项变为正式选项;取消选中时自动移除 --- ## 5. 三种尺寸 通过 `SizeType` 属性设置尺寸: ```xml ``` 尺寸也支持数据绑定,可在运行时动态切换: ```xml ``` ```csharp public class SelectViewModel : ReactiveObject { private SizeType _selectSizeType; public SizeType SelectSizeType { get => _selectSizeType; set => this.RaiseAndSetIfChanged(ref _selectSizeType, value); } } ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Sizes" 示例。 --- ## 6. 自定义下拉选项 通过 `OptionTemplate` 自定义下拉选项的渲染方式: ```xml ``` 自定义选项类型: ```csharp public record CustomOption : SelectOption { public string? Description { get; init; } public string? Emoji { get; init; } } ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Custom dropdown options" 示例。 --- ## 7. 选项分组 通过 `IsGroupEnabled="True"` 启用选项分组,每个选项通过 `Group` 属性指定所属分组: ```xml ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Option Group" 示例。 --- ## 8. 样式变体 通过 `StyleVariant` 属性设置三种样式变体: ```xml ``` 每种变体同时支持单选和多选模式。 > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Variants" 示例。 --- ## 9. 隐藏已选选项 多选模式下,通过 `IsHideSelectedOptions="True"` 在下拉中隐藏已选项: ```xml ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Hide Already Selected" 示例。 --- ## 10. 验证状态 通过 `Status` 属性设置 Error 或 Warning 状态: ```xml ``` **说明**:Error 状态显示红色边框,Warning 状态显示橙色边框。 > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Status" 示例。 --- ## 11. 最大选择数限制 通过 `MaxCount` 限制最大可选数量,配合 `IsShowMaxCountIndicator` 显示计数指示器: ```xml ``` **说明**:当已选数量达到 `MaxCount` 后,未选选项将被禁用。指示器显示 `当前数/最大数`。 > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Max Count" 示例。 --- ## 12. 响应式标签折叠 多选模式下处理大量已选标签的展示: ### 响应式自动折叠 ```xml ``` ### 固定最大标签数 ```xml ``` **说明**: - `IsResponsiveTagMode="True"`:根据控件实际宽度自动计算可见标签数量 - `MaxTagCount="5"`:固定最多显示 5 个标签,超出部分折叠为 `+N` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Responsive maxTagCount" 示例。 --- ## 13. 前缀和后缀 通过 `ContentLeftAddOn` 和 `ContentRightAddOn` 添加前后缀内容: ```xml ``` 前缀和后缀同样支持多选模式: ```xml ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml` 中 "Prefix and Suffix" 示例。 --- ## 14. 异步加载选项 通过 `OptionsLoader` 属性绑定 `ISelectOptionsAsyncLoader` 实现远程数据加载: ```csharp // 实现异步加载器 public class SelectOptionsAsyncLoader : ISelectOptionsAsyncLoader { public async Task LoadAsync(object? context, CancellationToken token) { await Task.Delay(TimeSpan.FromMilliseconds(600), token); // 模拟网络请求 var options = new List { new SelectOption { Header = "Jack", Content = "jack" }, new SelectOption { Header = "Lucy", Content = "lucy" }, new SelectOption { Header = "Yiminghe", Content = "yiminghe" }, new SelectOption { Header = "Disabled", Content = "disabled", IsEnabled = false } }; return new SelectOptionsLoadResult { Data = options, StatusCode = RpcStatusCode.Success }; } } ``` ```xml ``` 在 code-behind 中绑定加载器: ```csharp this.OneWayBind(viewModel, vm => vm.SelectOptionsAsyncLoader, v => v.AsyncLoadSelect.OptionsLoader) .DisposeWith(disposables); ``` **加载行为**: - 首次点击打开时触发异步加载 - 加载期间显示旋转的 `LoadingOutlined` 图标 - 加载成功后自动填充选项并展开下拉 - 仅加载一次,后续点击直接展开 > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/ViewModels/DataEntry/SelectViewModel.cs` 中的 `SelectOptionsAsyncLoader` 实现。 --- ## 15. 数据绑定(OptionsSource) 通过 `OptionsSource` 属性绑定数据集合: ```csharp // ViewModel public class SelectViewModel : ReactiveObject { private List? _randomOptions; public List? RandomOptions { get => _randomOptions; set => this.RaiseAndSetIfChanged(ref _randomOptions, value); } } // 初始化数据 var options = new List(); for (var i = 10; i < 36; i++) { var base36Str = ConvertToBase36(i); options.Add(new SelectOption { Header = base36Str + i, Content = base36Str + i }); } viewModel.RandomOptions = options; ``` 在 code-behind 中绑定: ```csharp this.OneWayBind(viewModel, vm => vm.RandomOptions, v => v.MultiSelect1.OptionsSource) .DisposeWith(disposables); ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml.cs` --- ## 16. 选中值绑定 ### 单选模式 ```csharp // 通过 SelectedOption 获取当前选中项 this.OneWayBind(viewModel, vm => vm.DefaultSelectedOptions, v => v.DefaultSelectedSelect.SelectedOptions) .DisposeWith(disposables); ``` ### 监听选择变更 ```csharp select.SelectionChanged += (sender, args) => { if (args.Mode == SelectMode.Single) { var selectedOption = args.NewValue as ISelectOption; // 处理单选变更... } else { var selectedOptions = args.NewValue as IList; // 处理多选变更... } }; ``` --- ## 常见组合模式 ### 表单内使用(带验证状态) ```xml ``` ### 联动选择 ```xml ``` ### 标签录入 ```xml ``` ### 分组搜索选择 ```xml ```