.NET 多平台应用 UI (.NET MAUI) CollectionView 定义控制项选择的以下属性:
-
SelectionMode,类型SelectionMode为选择模式。 -
SelectedItem,类型object为列表中的选定项。 此属性的默认绑定模式为TwoWay,在未选择任何项时具有null值。 -
SelectedItems,类型IList<object>为列表中的选定项。 此属性具有默认绑定模式OneWay,并且未选择任何项时具有null值。 -
SelectionChangedCommand,类型 ICommand,在所选项更改时执行。 -
SelectionChangedCommandParameter属于object类型,是传递给SelectionChangedCommand的参数。
所有这些属性都由 BindableProperty 对象提供支持,这意味着这些属性可以作为数据绑定的目标。
默认情况下, CollectionView 选择处于禁用状态。 但是,可以通过将 SelectionMode 属性值设置为 SelectionMode 枚举成员之一来更改此行为。
-
None– 指示无法选择项目。 这是默认值。 -
Single– 表示可以唯一地选择一个单项,并且所选项会被突出显示。 -
Multiple– 指示可以选择多个项,其中突出显示了选定项。
CollectionView 定义了一个事件,当 SelectionChanged 属性因用户选择列表中项或应用程序设置该属性而更改时,该事件会触发。 此外,当此 SelectedItems 属性发生更改时,也会触发该事件。
SelectionChanged事件附带的SelectionChangedEventArgs对象有两个属性,这两个属性的类型均为IReadOnlyList<object>。
-
PreviousSelection– 所选项的列表,在所选内容发生更改之前。 -
CurrentSelection– 在选择更改后选中的项列表。
此外, CollectionView 还有一个 UpdateSelectedItems 方法,该方法使用所选项的列表更新 SelectedItems 属性,同时仅触发单个更改通知。
单选
当属性SelectionMode设置为Single时,可以在CollectionView中选择一个项目。 选择某个项后,该 SelectedItem 属性将设置为所选项的值。 当此属性发生更改时,SelectionChangedCommand 会执行(SelectionChangedCommandParameter 的值将传递给 ICommand),并触发 SelectionChanged 事件。
以下 XAML 示例展示了一个 CollectionView,它能够响应单个项的选择:
<CollectionView ItemsSource="{Binding Monkeys}"
SelectionMode="Single"
SelectionChanged="OnCollectionViewSelectionChanged">
...
</CollectionView>
等效的 C# 代码为:
CollectionView collectionView = new CollectionView
{
SelectionMode = SelectionMode.Single
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.Monkeys);
collectionView.SelectionChanged += OnCollectionViewSelectionChanged;
在此代码示例中,SelectionChanged事件触发时会执行OnCollectionViewSelectionChanged事件处理程序,该处理程序会检索之前选定的项和当前选定的项。
void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
string previous = (e.PreviousSelection.FirstOrDefault() as Monkey)?.Name;
string current = (e.CurrentSelection.FirstOrDefault() as Monkey)?.Name;
...
}
重要
更改SelectionMode属性而引发的更改可以触发SelectionChanged事件。
以下屏幕截图显示了在CollectionView中选择单个项:
多项选择
当属性 SelectionMode 设置为 Multiple时,可以选择该属性中的 CollectionView 多个项。 当选择项被选中时,SelectedItems 属性将设置为被选中的项。 当此属性发生更改时,会执行SelectionChangedCommand(将SelectionChangedCommandParameter的值传递给ICommand),并触发SelectionChanged事件。
以下 XAML 示例展示了一个 CollectionView,它可以响应多项选择。
<CollectionView ItemsSource="{Binding Monkeys}"
SelectionMode="Multiple"
SelectionChanged="OnCollectionViewSelectionChanged">
...
</CollectionView>
等效的 C# 代码为:
CollectionView collectionView = new CollectionView
{
SelectionMode = SelectionMode.Multiple
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.Monkeys);
collectionView.SelectionChanged += OnCollectionViewSelectionChanged;
在此代码示例中,当SelectionChanged事件触发时,将执行OnCollectionViewSelectionChanged事件处理程序,该事件处理程序会检索以前选定的项和当前选定的项。
void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var previous = e.PreviousSelection;
var current = e.CurrentSelection;
...
}
重要
更改SelectionMode属性可以触发该SelectionChanged事件。
以下屏幕截图显示 CollectionView 中的多个项选择:
单个预选
当SelectionMode属性设置为Single时,可以通过将SelectedItem属性设置为CollectionView中的某一项来预选该项。 以下 XAML 示例演示了一个CollectionView,该控件预先选择单个项:
<CollectionView ItemsSource="{Binding Monkeys}"
SelectionMode="Single"
SelectedItem="{Binding SelectedMonkey}">
...
</CollectionView>
等效的 C# 代码为:
CollectionView collectionView = new CollectionView
{
SelectionMode = SelectionMode.Single
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.Monkeys);
collectionView.SetBinding(SelectableItemsView.SelectedItemProperty, static (MonkeysViewModel vm) => vm.SelectedMonkey);
注释
该 SelectedItem 属性的默认绑定模式为 TwoWay.
属性 SelectedItem 的数据绑定到连接的视图模型的属性 SelectedMonkey,该属性是类型 Monkey。 默认情况下, TwoWay 使用绑定,以便当用户更改所选项时,属性 SelectedMonkey 的值将设置为所选 Monkey 对象。 该 SelectedMonkey 属性在 MonkeysViewModel 类中定义,并设置为 Monkeys 集合的第四项。
public class MonkeysViewModel : INotifyPropertyChanged
{
...
public ObservableCollection<Monkey> Monkeys { get; private set; }
Monkey selectedMonkey;
public Monkey SelectedMonkey
{
get
{
return selectedMonkey;
}
set
{
if (selectedMonkey != value)
{
selectedMonkey = value;
}
}
}
public MonkeysViewModel()
{
...
selectedMonkey = Monkeys.Skip(3).FirstOrDefault();
}
...
}
因此,当CollectionView出现时,会预先选择列表中的第四项。
多项预选
当属性 SelectionMode 设置为 Multiple时,可以预先选择该属性中的 CollectionView 多个项。 下面的 XAML 示例演示了一个 CollectionView,可用于预先选择多个项目:
<CollectionView x:Name="collectionView"
ItemsSource="{Binding Monkeys}"
SelectionMode="Multiple"
SelectedItems="{Binding SelectedMonkeys}">
...
</CollectionView>
等效的 C# 代码为:
CollectionView collectionView = new CollectionView
{
SelectionMode = SelectionMode.Multiple
};
collectionView.SetBinding(ItemsView.ItemsSourceProperty, static (MonkeysViewModel vm) => vm.Monkeys);
collectionView.SetBinding(SelectableItemsView.SelectedItemsProperty, static (MonkeysViewModel vm) => vm.SelectedMonkeys);
注释
该 SelectedItems 属性的默认绑定模式为 OneWay.
属性 SelectedItems 被绑定到连接的视图模型的属性 SelectedMonkeys,其类型为 ObservableCollection<object>。 该 SelectedMonkeys 属性在类中 MonkeysViewModel 定义,并设置为集合中的 Monkeys 第二项、第四项和第五项:
namespace CollectionViewDemos.ViewModels
{
public class MonkeysViewModel : INotifyPropertyChanged
{
...
ObservableCollection<object> selectedMonkeys;
public ObservableCollection<object> SelectedMonkeys
{
get
{
return selectedMonkeys;
}
set
{
if (selectedMonkeys != value)
{
selectedMonkeys = value;
}
}
}
public MonkeysViewModel()
{
...
SelectedMonkeys = new ObservableCollection<object>()
{
Monkeys[1], Monkeys[3], Monkeys[4]
};
}
...
}
}
因此,当CollectionView出现时,列表中的第二项、第四项和第五项会被预先选择:
清除选择
SelectedItem和SelectedItems属性可以通过将它们或它们绑定的对象设置为null来清除。 当清除其中任一属性时,会触发SelectionChanged事件,CurrentSelection属性为空,并执行SelectionChangedCommand。
句柄重新选择
一种常见情况是,用户在CollectionView中选择一个项目,然后导航到另一个页面。 导航回时,该项仍处于选中状态,这将导致它们无法重新选择给定的项目。 若要启用重新选择,您应该清除 CollectionView 上的项目选择。
<CollectionView ...
SelectionChanged="OnCollectionViewSelectionChanged" />
等效的 C# 代码为:
CollectionView collectionView = new CollectionView();
collectionView.SelectionChanged += OnCollectionViewSelectionChanged;
以下示例显示了事件的 SelectionChanged 事件处理程序代码:
void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
var cv = (CollectionView)sender;
if (cv.SelectedItem == null)
return;
cv.SelectedItem = null;
}
更改所选项目颜色
CollectionView具有一个SelectedVisualState,可用于在CollectionView中启动对所选项目的视觉更改。 常见的 VisualState 用例是改变选中项目的背景颜色,如以下 XAML 示例所示:
<ContentPage ...>
<ContentPage.Resources>
<Style TargetType="Grid">
<Setter Property="VisualStateManager.VisualStateGroups">
<VisualStateGroupList>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Property="BackgroundColor"
Value="LightSkyBlue" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateGroupList>
</Setter>
</Style>
</ContentPage.Resources>
<Grid Margin="20">
<CollectionView ItemsSource="{Binding Monkeys}"
SelectionMode="Single">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
...
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</Grid>
</ContentPage>
重要
包含SelectedVisualState的Style必须具有一个TargetType属性值,该属性值应是DataTemplate的根元素类型,该根元素被设置为ItemTemplate属性值。
包含视觉状态的样式的等效 C# 代码为:
using static Microsoft.Maui.Controls.VisualStateManager;
...
Setter backgroundColorSetter = new() { Property = BackgroundColorProperty, Value = Colors.LightSkyBlue };
VisualState stateSelected = new() { Name = CommonStates.Selected, Setters = { backgroundColorSetter } };
VisualState stateNormal = new() { Name = CommonStates.Normal };
VisualStateGroup visualStateGroup = new() { Name = nameof(CommonStates), States = { stateSelected, stateNormal } };
VisualStateGroupList visualStateGroupList = new() { visualStateGroup };
Setter vsgSetter = new() { Property = VisualStateGroupsProperty, Value = visualStateGroupList };
Style style = new(typeof(Grid)) { Setters = { vsgSetter } };
// Add the style to the resource dictionary
Resources.Add(style);
在此示例中, Style.TargetType 属性值设置为 Grid 因为根元素 ItemTemplate 是一个 Grid。 指定当CollectionView中的某项被选中时,SelectedVisualState将该项的BackgroundColor设置为LightSkyBlue。
有关视觉状态的详细信息,请参阅 视觉状态。
禁用选择
CollectionView 选择功能默认禁用。 但是,如果 CollectionView 已启用选择功能,可以通过将 SelectionMode 属性设为 None 来禁用它。
<CollectionView ...
SelectionMode="None" />
等效的 C# 代码为:
CollectionView collectionView = new CollectionView
{
...
SelectionMode = SelectionMode.None
};
当属性 SelectionMode 设置为 None时,无法选择该 CollectionView 属性中的项,该 SelectedItem 属性将保持不变 null,并且 SelectionChanged 不会触发该事件。
注释
当选择一个项目并将SelectionMode属性从Single更改为None时,SelectedItem属性将被设置为null,并且SelectionChanged事件将使用空的CurrentSelection属性触发。
浏览示例