配置 CollectionView 项选择
.NET Multi-platform App 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
事件,当 SelectedItem
属性发生更改时(由于用户从列表中选择项或应用程序设置了属性)会引发该事件。 此外,当 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, "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, "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, "Monkeys");
collectionView.SetBinding(SelectableItemsView.SelectedItemProperty, "SelectedMonkey");
注意
SelectedItem
属性的默认绑定模式为 TwoWay
。
SelectedItem
属性数据绑定到类型为 Monkey
的已连接视图模型的 SelectedMonkey
属性。 默认情况下使用 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, "Monkeys");
collectionView.SetBinding(SelectableItemsView.SelectedItemsProperty, "SelectedMonkeys");
注意
SelectedItems
属性的默认绑定模式为 OneWay
。
SelectedItems
属性数据绑定到类型为 ObservableCollection<object>
的已连接视图模型的 SelectedMonkeys
属性。 该 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
来清除这两个属性。 清除其中任一属性时,将通过空 CurrentSelection
属性引发 SelectionChanged
事件,并执行 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 具有的 Selected
VisualState 可用于启动对 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>
重要
若 Style 包含 Selected
VisualState,其 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。 Selected
VisualState 指定在选定 CollectionView 中的项时,该项的 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
,并将通过空的 CurrentSelection
属性引发 SelectionChanged
事件。