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 属性数据绑定到已连接视图模型的 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, "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 来清除这两个属性。
更改选定项的颜色
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>
    <StackLayout Margin="20">
        <CollectionView ItemsSource="{Binding Monkeys}"
                        SelectionMode="Single">
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <Grid Padding="10">
                        ...
                    </Grid>
                </DataTemplate>
            </CollectionView.ItemTemplate>
        </CollectionView>
    </StackLayout>
</ContentPage>
重要
若 Style 包含 Selected VisualState,其 TargetType 属性值必须是 DataTemplate(设置为 ItemTemplate 属性值)的根元素类型。
在此示例中,Style.TargetType 属性值被设置为 Grid,因为 ItemTemplate 的根元素为 Grid。 指定SelectedVisualState在选定项CollectionView时,BackgroundColor该项的设置为LightSkyBlue:
若要详细了解可视状态,请参阅 Xamarin.Forms 可视状态管理器。
禁用选择
默认情况下,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 事件。




