配置 CollectionView 项选择

Browse sample.浏览示例

.NET Multi-platform 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 定义当 SelectedItem 属性发生更改时触发的 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, "Monkeys");
collectionView.SelectionChanged += OnCollectionViewSelectionChanged;

在此代码示例中,OnCollectionViewSelectionChanged 事件处理程序在 SelectionChanged 事件触发时执行,事件处理程序会检索之前选定的项和当前选定的项:

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    string previous = (e.PreviousSelection.FirstOrDefault() as Monkey)?.Name;
    string current = (e.CurrentSelection.FirstOrDefault() as Monkey)?.Name;
    ...
}

重要

SelectionChanged 事件可以通过因更改 SelectionMode 属性而发生的更改所触发。

以下屏幕截图显示了 CollectionView 中单项选择:

Screenshot of a CollectionView vertical list with single selection.

多重选择

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;

在此代码示例中,OnCollectionViewSelectionChanged 事件处理程序在 SelectionChanged 事件触发时执行,事件处理程序会检索以前选定的项和当前选定的项:

void OnCollectionViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var previous = e.PreviousSelection;
    var current = e.CurrentSelection;
    ...
}

重要

SelectionChanged 事件可以通过因更改 SelectionMode 属性而发生的更改所触发。

以下屏幕截图显示了 CollectionView 中的多项选择:

Screenshot of a CollectionView vertical list with multiple selection.

单个预选

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 属性将数据绑定到连接视图模型的 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 时,将预先选择列表中的第四个项:

Screenshot of a CollectionView vertical list with single preselection.

多个预选

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 属性将数据绑定到连接视图模型的 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 时,将预选列表中的第二项、第四项和第五个项:

Screenshot of a CollectionView vertical list with multiple preselection.

清除选择

可以通过将 SelectedItemSelectedItems 属性或与它们绑定的对象设置为 null 来清除它们。 清除其中任一属性时,将使用空 CurrentSelection 属性引发 SelectionChanged 事件,并执行 SelectionChangedCommand

更改选定项颜色

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>

重要

包含 SelectedVisualStateStyle 必须有 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 的根元素为 GridSelectedVisualState 指定在选择 CollectionView 中的项时,该项的 BackgroundColor 将设置为 LightSkyBlue

Screenshot of a CollectionView vertical list with a custom single selection color.

有关视觉状态的详细信息,请参阅视觉状态

禁用选择

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 事件。