13 KiB
ListView 使用文档
本文档介绍 AtomUI ListView 控件的各种使用方式,示例代码摘自 Gallery 演示程序。
📖 Gallery 源码位置:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml
前置准备
在 AXAML 中使用 ListView,需要引入以下命名空间:
xmlns:atom="https://atomui.net"
在 C# 代码中引入:
using AtomUI.Desktop.Controls; // ListView, ListViewItem, Pagination
using AtomUI.Controls; // SizeType 等共享类型
using AtomUI.Controls.Data; // IListItemData, ListItemData, ListSortDescription
1. 基础用法
ListView 通过 ItemsSource 绑定数据源,数据项需要实现 IListItemData 接口:
<atom:ListView ItemsSource="{Binding ListItems}" />
// ViewModel 或 Code-behind 中准备数据
var listItems = new List<IListItemData>
{
new ListItemData { Content = "Blue" },
new ListItemData { Content = "Green" },
new ListItemData { Content = "Red" },
new ListItemData { Content = "Yellow" }
};
默认情况下,ListView 使用内置的 ItemTemplate 渲染 IListItemData.Content 属性为文本:
<!-- 默认 ItemTemplate(内置,通常无需手动指定) -->
<DataTemplate x:DataType="atom:IListItemData">
<atom:TextBlock Text="{Binding Content}" />
</DataTemplate>
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml中 "Basic usage" 示例。
2. 选择模式
通过 SelectionMode 属性设置选择模式,结合 IsShowSelectedIndicator 展示选中状态:
<atom:ListView SelectionMode="Single"
ItemsSource="{Binding SelectionListItems}"
IsShowSelectedIndicator="True" />
单选模式(默认)
<atom:ListView SelectionMode="Single"
ItemsSource="{Binding Items}"
IsShowSelectedIndicator="True" />
多选模式
<atom:ListView SelectionMode="Multiple"
ItemsSource="{Binding Items}"
IsShowSelectedIndicator="True" />
Toggle 模式
<atom:ListView SelectionMode="Toggle"
ItemsSource="{Binding Items}"
IsShowSelectedIndicator="True" />
动态切换选择模式
<StackPanel Spacing="20">
<StackPanel Orientation="Horizontal" Spacing="5">
<atom:TextBlock VerticalAlignment="Center">Selection Mode:</atom:TextBlock>
<atom:OptionButtonGroup ButtonStyle="Solid" Name="SelectionModeOptionGroup">
<atom:OptionButton IsChecked="True"
Tag="{x:Static SelectionMode.Single}">Single</atom:OptionButton>
<atom:OptionButton Tag="{x:Static SelectionMode.Multiple}">Multiple</atom:OptionButton>
<atom:OptionButton Tag="{x:Static SelectionMode.Toggle}">Toggle</atom:OptionButton>
</atom:OptionButtonGroup>
</StackPanel>
<atom:ListView SelectionMode="{Binding SelectionMode}"
ItemsSource="{Binding SelectionListItems}"
IsShowSelectedIndicator="True" />
</StackPanel>
// Code-behind 处理选择模式切换
SelectionModeOptionGroup.OptionCheckedChanged += (sender, e) =>
{
if (DataContext is ListViewModel viewModel &&
e.CheckedOption.IsChecked == true &&
e.CheckedOption.Tag is SelectionMode selectionMode)
{
viewModel.SelectionMode = selectionMode;
}
};
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml中 "Selection" 示例。
3. 分组
通过 IsGroupEnabled="True" 开启分组功能。数据项需要实现 IGroupHeader 接口或通过 Group 属性指定分组:
<atom:ListView ItemsSource="{Binding GroupListItems}"
IsGroupEnabled="True"
Height="300" />
// 数据准备 — 使用 Group 属性指定分组
var groupListItems = new List<IListItemData>
{
new ListItemData { Content = "Red", Group = "Basic Colors" },
new ListItemData { Content = "Orange", Group = "Basic Colors" },
new ListItemData { Content = "Green", Group = "Basic Colors" },
new ListItemData { Content = "Blue", Group = "Basic Colors" },
new ListItemData { Content = "Brown", Group = "Neutral Colors" },
new ListItemData { Content = "White", Group = "Neutral Colors" },
new ListItemData { Content = "Black", Group = "Neutral Colors" },
new ListItemData { Content = "Turquoise", Group = "Specific Shades" },
new ListItemData { Content = "Violet", Group = "Specific Shades" },
new ListItemData { Content = "Magenta", Group = "Specific Shades" },
};
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml中 "Group" 示例。
4. 禁用项
通过设置 IListItemData.IsEnabled = false 禁用特定列表项:
<atom:ListView ItemsSource="{Binding ListItemsWidthDisabled}" />
var listItems = new List<IListItemData>
{
new ListItemData { Content = "Blue" },
new ListItemData { Content = "Green" },
new ListItemData { Content = "Red" },
new ListItemData { Content = "Yellow", IsEnabled = false } // 此项被禁用
};
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml中 "Item disabled" 示例。
5. 空状态
当数据源为空时,ListView 自动显示空状态指示器。通过按钮动态增删项目来演示空/非空切换:
<StackPanel Spacing="12">
<StackPanel Orientation="Horizontal" Spacing="8">
<atom:Button Content="Add Item" Click="HandleAddEmptyItemClicked" />
<atom:Button Content="Remove Item" Click="HandleRemoveEmptyItemClicked" />
</StackPanel>
<atom:ListView ItemsSource="{Binding EmptyDemoItems}"
IsShowEmptyIndicator="True" />
</StackPanel>
private void HandleAddEmptyItemClicked(object? sender, RoutedEventArgs e)
{
if (DataContext is not ListViewModel viewModel) return;
var items = viewModel.EmptyDemoItems != null
? new List<IListItemData>(viewModel.EmptyDemoItems)
: new List<IListItemData>();
items.Add(new ListItemData { Content = "Dynamic item" });
viewModel.EmptyDemoItems = items;
}
private void HandleRemoveEmptyItemClicked(object? sender, RoutedEventArgs e)
{
if (DataContext is not ListViewModel viewModel) return;
if (viewModel.EmptyDemoItems is null || viewModel.EmptyDemoItems.Count <= 1)
{
viewModel.EmptyDemoItems = [];
return;
}
var items = new List<IListItemData>(viewModel.EmptyDemoItems);
items.RemoveAt(items.Count - 1);
viewModel.EmptyDemoItems = items;
}
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml中 "Empty" 示例。
6. 过滤
通过 Filter 和 FilterValue 属性对数据进行过滤。可使用内置的 ValueFilterProvider 标记扩展:
<atom:ListView ItemsSource="{Binding FilteredGroupListItems}"
Filter="{atom:ValueFilterProvider Contains}"
FilterValue="a" />
上述配置会过滤出内容包含字母 "a" 的所有项目。
自定义过滤值提取
如果需要按数据项的特定属性过滤,可设置 FilterValueSelector:
// 按自定义属性过滤
listView.FilterValueSelector = record =>
{
if (record is MyDataItem item)
return item.Category;
return null;
};
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml中 "Filter" 示例。
7. 排序
通过 SortDescriptions 属性对数据进行排序:
<atom:ListView Name="OrderedList"
ItemsSource="{Binding OrderedGroupListItems}"
IsGroupEnabled="True" />
// Code-behind 设置排序
OrderedList.SortDescriptions = [ListSortDescription.FromPath("Content")];
ListSortDescription.FromPath 根据属性路径创建排序描述,默认为升序。
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml中 "Ordered" 示例。
8. 分页
ListView 支持内置分页功能,通过 BottomPagination(或 TopPagination)放置分页器,配合 PageSize 设置每页数量:
<atom:ListView ItemsSource="{Binding PaginationListItems}"
PaginationVisibility="Bottom"
SelectionMode="Multiple"
Height="400"
PageSize="100">
<atom:ListView.BottomPagination>
<atom:Pagination />
</atom:ListView.BottomPagination>
</atom:ListView>
// 准备大量数据用于分页
var list = new List<IListItemData>();
for (var i = 0; i < 2000; i++)
{
list.Add(new ListItemData
{
ItemKey = $"{i}",
Content = $"Content {i}"
});
}
viewModel.PaginationListItems = list;
分页器位置控制
<!-- 仅顶部分页 -->
<atom:ListView PaginationVisibility="Top" PageSize="50">
<atom:ListView.TopPagination>
<atom:Pagination />
</atom:ListView.TopPagination>
</atom:ListView>
<!-- 顶部 + 底部同时显示 -->
<atom:ListView PaginationVisibility="Both" PageSize="50">
<atom:ListView.TopPagination>
<atom:Pagination />
</atom:ListView.TopPagination>
<atom:ListView.BottomPagination>
<atom:Pagination />
</atom:ListView.BottomPagination>
</atom:ListView>
<!-- 隐藏分页(仍使用 PageSize 分页数据) -->
<atom:ListView PaginationVisibility="None" PageSize="50" />
分页器对齐
<atom:ListView TopPaginationAlign="Center"
BottomPaginationAlign="End"
PageSize="50">
<!-- ... -->
</atom:ListView>
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataDisplay/ListShowCase.axaml中 "Pagination list" 示例。
9. 选择绑定
绑定 SelectedItem
<atom:ListView ItemsSource="{Binding Items}"
SelectedItem="{Binding CurrentItem}" />
绑定 SelectedIndex
<atom:ListView ItemsSource="{Binding Items}"
SelectedIndex="{Binding CurrentIndex}" />
多选绑定 SelectedItems
<atom:ListView ItemsSource="{Binding Items}"
SelectionMode="Multiple"
SelectedItems="{Binding SelectedItemsList}" />
使用 SelectedValue + SelectedValueBinding
<atom:ListView ItemsSource="{Binding Items}"
SelectedValue="{Binding SelectedId}"
SelectedValueBinding="{Binding ItemKey}" />
监听选择变化事件
<atom:ListView ItemsSource="{Binding Items}"
SelectionChanged="HandleSelectionChanged" />
private void HandleSelectionChanged(object? sender, SelectionChangedEventArgs e)
{
foreach (var added in e.AddedItems)
{
// 处理新选中的项
}
foreach (var removed in e.RemovedItems)
{
// 处理取消选中的项
}
}
10. 加载状态
通过 IsOperating 属性展示加载状态覆盖层:
<atom:ListView ItemsSource="{Binding Items}"
IsOperating="{Binding IsLoading}"
OperatingMsg="Loading data..." />
// 模拟异步加载
public async Task LoadDataAsync()
{
IsLoading = true;
try
{
var data = await _service.GetDataAsync();
Items = data;
}
finally
{
IsLoading = false;
}
}
11. 监听项目点击
<atom:ListView ItemsSource="{Binding Items}"
ItemClicked="HandleItemClicked" />
private void HandleItemClicked(object? sender, ListViewItemClickedEventArgs e)
{
var clickedItem = e.Item;
// 处理点击逻辑
}
常见组合模式
基础数据列表
<atom:ListView ItemsSource="{Binding Items}"
IsShowSelectedIndicator="True"
SelectionMode="Single" />
可搜索的过滤列表
<StackPanel Spacing="10">
<atom:SearchEdit PlaceholderText="Search..."
TextChanged="HandleSearchTextChanged" />
<atom:ListView Name="FilterableList"
ItemsSource="{Binding Items}"
Filter="{atom:ValueFilterProvider Contains}" />
</StackPanel>
private void HandleSearchTextChanged(object? sender, TextChangedEventArgs e)
{
if (sender is SearchEdit searchEdit)
{
FilterableList.FilterValue = searchEdit.Text?.Trim();
}
}
分组 + 排序列表
<atom:ListView ItemsSource="{Binding GroupItems}"
IsGroupEnabled="True"
Height="400" />
// 同时设置排序
listView.SortDescriptions = [ListSortDescription.FromPath("Content")];
大数据分页列表
<atom:ListView ItemsSource="{Binding LargeDataSet}"
PageSize="50"
SelectionMode="Multiple"
PaginationVisibility="Bottom"
BottomPaginationAlign="End"
Height="500">
<atom:ListView.BottomPagination>
<atom:Pagination />
</atom:ListView.BottomPagination>
</atom:ListView>