18 KiB
Select 使用文档
本文档介绍 AtomUI Select 控件的各种使用方式,示例代码摘自 Gallery 演示程序。
📖 Gallery 源码位置:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml
前置准备
在 AXAML 中使用 Select,需要引入以下命名空间:
xmlns:atom="https://atomui.net"
xmlns:antdicons="https://atomui.net/icons/antdesign"
在 C# 代码中引入:
using AtomUI.Desktop.Controls; // Select, SelectOption, ISelectOption
using AtomUI.Controls; // SizeType, InputControlStyleVariant 等共享类型
1. 基本用法
最基本的 Select 用法——单选模式,声明式定义选项:
<atom:Select Mode="Single" PlaceholderText="Please select" Width="120"
DefaultValues="lucy">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
<atom:SelectOption Header="Yiminghe" Content="yiminghe" />
<atom:SelectOption Header="Disabled" IsEnabled="False" Content="disabled" />
</atom:Select>
说明:
Header是显示文本,Content是选项的值DefaultValues通过Content值匹配来设置默认选中项IsEnabled="False"可禁用单个选项
禁用整个 Select
<atom:Select Mode="Single" PlaceholderText="Please select" IsEnabled="False" Width="120"
DefaultValues="lucy">
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
允许清空
<atom:Select Mode="Single" PlaceholderText="Please select" IsAllowClear="True" Width="120">
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
2. 搜索过滤
通过 IsFilterEnabled="True" 启用展开时的搜索过滤:
<atom:Select Mode="Single" PlaceholderText="Please select" IsFilterEnabled="True">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
<atom:SelectOption Header="Tom" Content="tom" />
</atom:Select>
默认行为:按 Header 属性进行模糊匹配。
自定义搜索过滤
使用内置过滤器或自定义 IValueFilter 实现:
<atom:Select Name="CustomSearchSelect"
Mode="Single"
PlaceholderText="Select a person"
IsFilterEnabled="True"
Filter="{atom:ValueFilterProvider Contains}">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
<atom:SelectOption Header="Tom" Content="tom" />
</atom:Select>
在 code-behind 中设置自定义过滤器:
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" 启用多选,已选项以标签形式展示:
<atom:Select Name="MultiSelect1"
Mode="Multiple"
PlaceholderText="Select a person"
IsAllowClear="True"
HorizontalAlignment="Stretch"
IsFilterEnabled="True"
DefaultValues="a10, c12" />
说明:
- 多选模式下,
DefaultValues支持逗号分隔的多个值 - 每个已选项显示为可关闭的标签(Tag)
- 点击标签上的关闭按钮可取消选中
Backspace/Delete键可删除最后一个标签
禁用多选 Select
<atom:Select Name="MultiSelect2"
Mode="Multiple"
PlaceholderText="Select a person"
IsAllowClear="True"
HorizontalAlignment="Stretch"
DefaultValues="a10, c12"
IsEnabled="False" />
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml中 "multiple selection" 示例。
4. 标签模式(Tags)
通过 Mode="Tags" 允许用户从列表选择或自由输入创建新标签:
<atom:Select Name="TagsModeSelect"
Mode="Tags"
PlaceholderText="Tags Mode"
HorizontalAlignment="Stretch"
IsFilterEnabled="False" />
Tags 模式特殊行为:
- 搜索功能自动启用(即使
IsFilterEnabled="False") - 当输入内容无匹配项时,自动创建一个新的临时选项
- 选中后临时选项变为正式选项;取消选中时自动移除
5. 三种尺寸
通过 SizeType 属性设置尺寸:
<!-- 大号 -->
<atom:Select Mode="Single"
SizeType="Large"
PlaceholderText="Select a person"
DefaultValues="a10"
Width="200" />
<!-- 中号(默认) -->
<atom:Select Mode="Single"
SizeType="Middle"
PlaceholderText="Select a person"
DefaultValues="a10"
Width="200" />
<!-- 小号 -->
<atom:Select Mode="Single"
SizeType="Small"
PlaceholderText="Select a person"
DefaultValues="a10"
Width="200" />
尺寸也支持数据绑定,可在运行时动态切换:
<atom:Select Mode="Single"
SizeType="{Binding SelectSizeType}"
PlaceholderText="Select a person"
Width="200" />
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 自定义下拉选项的渲染方式:
<atom:Select Mode="Multiple" PlaceholderText="Please select"
IsFilterEnabled="True"
HorizontalAlignment="Stretch"
IsAllowClear="True">
<views:CustomOption Header="China" Content="china" Description="China (中国)" Emoji="🇨🇳" />
<views:CustomOption Header="USA" Content="usa" Description="USA (美国)" Emoji="🇺🇸" />
<views:CustomOption Header="Japan" Content="japan" Description="Japan (日本)" Emoji="🇯🇵" />
<views:CustomOption Header="Korea" Content="korea" Description="Korea (韩国)" Emoji="🇰🇷" />
<atom:Select.OptionTemplate>
<DataTemplate x:DataType="views:CustomOption">
<StackPanel Orientation="Horizontal" Spacing="5">
<TextBlock Text="{Binding Emoji}" />
<TextBlock Text="{Binding Description}" />
</StackPanel>
</DataTemplate>
</atom:Select.OptionTemplate>
</atom:Select>
自定义选项类型:
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 属性指定所属分组:
<atom:Select Mode="Single" PlaceholderText="Please select"
DefaultValues="lucy"
Width="200"
IsGroupEnabled="True"
IsFilterEnabled="True">
<atom:SelectOption Header="Jack" Content="jack" Group="Manager" />
<atom:SelectOption Header="Lucy" Content="lucy" Group="Manager" />
<atom:SelectOption Header="Chloe" Content="chloe" Group="engineer" />
<atom:SelectOption Header="Lucas" Content="lucas" Group="engineer" />
</atom:Select>
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml中 "Option Group" 示例。
8. 样式变体
通过 StyleVariant 属性设置三种样式变体:
<!-- Outlined(默认) -->
<atom:Select Mode="Single" PlaceholderText="Outline" HorizontalAlignment="Stretch">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
<!-- Filled -->
<atom:Select Mode="Single" PlaceholderText="Filled" HorizontalAlignment="Stretch"
StyleVariant="Filled">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
<!-- Borderless -->
<atom:Select Mode="Single" PlaceholderText="Borderless" HorizontalAlignment="Stretch"
StyleVariant="Borderless">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
每种变体同时支持单选和多选模式。
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml中 "Variants" 示例。
9. 隐藏已选选项
多选模式下,通过 IsHideSelectedOptions="True" 在下拉中隐藏已选项:
<atom:Select Mode="Multiple"
PlaceholderText="Inserted are removed"
IsHideSelectedOptions="True"
IsFilterEnabled="True"
HorizontalAlignment="Stretch">
<atom:SelectOption Header="Apples" Content="Apples" />
<atom:SelectOption Header="Nails" Content="Nails" />
<atom:SelectOption Header="Bananas" Content="Bananas" />
<atom:SelectOption Header="Helicopters" Content="Helicopters" />
</atom:Select>
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml中 "Hide Already Selected" 示例。
10. 验证状态
通过 Status 属性设置 Error 或 Warning 状态:
<atom:Select Mode="Single" HorizontalAlignment="Stretch" Status="Error" />
<atom:Select Mode="Single" HorizontalAlignment="Stretch" Status="Warning" />
说明:Error 状态显示红色边框,Warning 状态显示橙色边框。
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml中 "Status" 示例。
11. 最大选择数限制
通过 MaxCount 限制最大可选数量,配合 IsShowMaxCountIndicator 显示计数指示器:
<atom:Select Mode="Multiple"
HorizontalAlignment="Stretch"
PlaceholderText="Please select"
MaxCount="3"
IsShowMaxCountIndicator="True">
<atom:SelectOption Header="Ava Swift" Content="Ava Swift" />
<atom:SelectOption Header="Cole Reed" Content="Cole Reed" />
<atom:SelectOption Header="Mia Blake" Content="Mia Blake" />
<atom:SelectOption Header="Jake Stone" Content="Jake Stone" />
<atom:SelectOption Header="Lily Lane" Content="Lily Lane" />
<atom:SelectOption Header="Ryan Chase" Content="Ryan Chase" />
<atom:SelectOption Header="Zoe Fox" Content="Zoe Fox" />
<atom:SelectOption Header="Alex Grey" Content="Alex Grey" />
<atom:SelectOption Header="Elle Blair" Content="Elle Blair" />
</atom:Select>
说明:当已选数量达到 MaxCount 后,未选选项将被禁用。指示器显示 当前数/最大数。
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml中 "Max Count" 示例。
12. 响应式标签折叠
多选模式下处理大量已选标签的展示:
响应式自动折叠
<atom:Select Name="MaxTagSelect1"
Mode="Multiple"
PlaceholderText="Select Item..."
HorizontalAlignment="Stretch"
IsFilterEnabled="True"
IsResponsiveTagMode="True" />
固定最大标签数
<atom:Select Name="MaxTagSelect3"
Mode="Multiple"
PlaceholderText="Select Item..."
HorizontalAlignment="Stretch"
IsFilterEnabled="True"
MaxTagCount="5" />
说明:
IsResponsiveTagMode="True":根据控件实际宽度自动计算可见标签数量MaxTagCount="5":固定最多显示 5 个标签,超出部分折叠为+N
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml中 "Responsive maxTagCount" 示例。
13. 前缀和后缀
通过 ContentLeftAddOn 和 ContentRightAddOn 添加前后缀内容:
<!-- 文本前缀 -->
<atom:Select Mode="Single"
PlaceholderText="Outline"
DefaultValues="lucy"
Width="200"
ContentLeftAddOn="User">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
<!-- 图标后缀 -->
<atom:Select Mode="Single" PlaceholderText="Please select"
DefaultValues="lucy"
IsFilterEnabled="True"
Width="200"
ContentRightAddOn="{antdicons:AntDesignIconProvider Kind=SmileOutlined}">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
前缀和后缀同样支持多选模式:
<atom:Select Mode="Multiple"
PlaceholderText="Outline"
DefaultValues="lucy"
Width="200"
ContentLeftAddOn="User">
<atom:SelectOption Header="Jack" Content="jack" />
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml中 "Prefix and Suffix" 示例。
14. 异步加载选项
通过 OptionsLoader 属性绑定 ISelectOptionsAsyncLoader 实现远程数据加载:
// 实现异步加载器
public class SelectOptionsAsyncLoader : ISelectOptionsAsyncLoader
{
public async Task<SelectOptionsLoadResult> LoadAsync(object? context, CancellationToken token)
{
await Task.Delay(TimeSpan.FromMilliseconds(600), token); // 模拟网络请求
var options = new List<ISelectOption>
{
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
};
}
}
<atom:Select Name="AsyncLoadSelect"
Mode="Single"
PlaceholderText="Please select"
Width="120"
DefaultValues="lucy">
<atom:SelectOption Header="Lucy" Content="lucy" />
</atom:Select>
在 code-behind 中绑定加载器:
this.OneWayBind(viewModel, vm => vm.SelectOptionsAsyncLoader, v => v.AsyncLoadSelect.OptionsLoader)
.DisposeWith(disposables);
加载行为:
- 首次点击打开时触发异步加载
- 加载期间显示旋转的
LoadingOutlined图标 - 加载成功后自动填充选项并展开下拉
- 仅加载一次,后续点击直接展开
📖 参考:
controlgallery/AtomUIGallery/ShowCases/ViewModels/DataEntry/SelectViewModel.cs中的SelectOptionsAsyncLoader实现。
15. 数据绑定(OptionsSource)
通过 OptionsSource 属性绑定数据集合:
// ViewModel
public class SelectViewModel : ReactiveObject
{
private List<SelectOption>? _randomOptions;
public List<SelectOption>? RandomOptions
{
get => _randomOptions;
set => this.RaiseAndSetIfChanged(ref _randomOptions, value);
}
}
// 初始化数据
var options = new List<SelectOption>();
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 中绑定:
this.OneWayBind(viewModel, vm => vm.RandomOptions, v => v.MultiSelect1.OptionsSource)
.DisposeWith(disposables);
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/SelectShowCase.axaml.cs
16. 选中值绑定
单选模式
// 通过 SelectedOption 获取当前选中项
this.OneWayBind(viewModel, vm => vm.DefaultSelectedOptions, v => v.DefaultSelectedSelect.SelectedOptions)
.DisposeWith(disposables);
监听选择变更
select.SelectionChanged += (sender, args) =>
{
if (args.Mode == SelectMode.Single)
{
var selectedOption = args.NewValue as ISelectOption;
// 处理单选变更...
}
else
{
var selectedOptions = args.NewValue as IList<ISelectOption>;
// 处理多选变更...
}
};
常见组合模式
表单内使用(带验证状态)
<StackPanel Orientation="Vertical" Spacing="10">
<atom:Select Mode="Single"
PlaceholderText="请选择城市"
HorizontalAlignment="Stretch"
Status="Error">
<atom:SelectOption Header="北京" Content="beijing" />
<atom:SelectOption Header="上海" Content="shanghai" />
</atom:Select>
</StackPanel>
联动选择
<StackPanel Orientation="Horizontal" Spacing="10">
<atom:Select Mode="Single" PlaceholderText="Province" Width="150">
<atom:SelectOption Header="Zhejiang" Content="zhejiang" />
<atom:SelectOption Header="Jiangsu" Content="jiangsu" />
</atom:Select>
<atom:Select Mode="Single" PlaceholderText="City" Width="150">
<atom:SelectOption Header="Hangzhou" Content="hangzhou" />
<atom:SelectOption Header="Ningbo" Content="ningbo" />
</atom:Select>
</StackPanel>
标签录入
<atom:Select Mode="Tags"
PlaceholderText="输入标签后回车"
HorizontalAlignment="Stretch"
IsAllowClear="True" />
分组搜索选择
<atom:Select Mode="Single"
PlaceholderText="Search and select"
Width="250"
IsGroupEnabled="True"
IsFilterEnabled="True"
IsAllowClear="True">
<atom:SelectOption Header="Jack" Content="jack" Group="Manager" />
<atom:SelectOption Header="Lucy" Content="lucy" Group="Manager" />
<atom:SelectOption Header="Chloe" Content="chloe" Group="Engineer" />
<atom:SelectOption Header="Lucas" Content="lucas" Group="Engineer" />
</atom:Select>