Xamarin.Forms CollectionView 选取功能详解

Viewed 0

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,也会引发此事件。事件 SelectionChangedEventArgs 随附 SelectionChanged 的物件有两个属性,两者都是类型 IReadOnlyList<object>

  • PreviousSelection – 选取项目变更之前选取的项目清单。
  • CurrentSelection – 选取项目变更之后选取的项目清单。

此外,还有一个 UpdateSelectedItems 方法,CollectionView 这个方法会使用选取的专案清单来更新 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;
    ...
}

多重选取

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;

在此程式代码范例中 SelectionChangedOnCollectionViewSelectionChanged 事件处理程式会在事件引发时执行,事件处理程式会撷取先前选取的专案,以及目前选取的专案:

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

单一预先选取

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 资料会系结至 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 资料会系结至 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,会预先选取清单中的第二个、第四个和第五个专案。

清除选取专案

SelectedItemSelectedItems 属性可以藉由将和属性设定为,或将它们系结至 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.TargetType,属性值会设定为 Grid,因为的 ItemTemplate 根元素是 GridSelected VisualState 指定选取的 CollectionView 项目时,BackgroundColor 专案的会设定为 LightSkyBlue

停用选取范围

CollectionView 选取项目预设为停用。不过,如果 CollectionView 已启用选取专案,则可以将属性设定 SelectionModeNone 来停用:

<CollectionView ...
                SelectionMode="None" />

对等的 C# 程式码为:

CollectionView collectionView = new CollectionView
{
    ...
    SelectionMode = SelectionMode.None
};

SelectionMode 属性设定为 None 时,无法选取 CollectionView 中的专案,SelectedItem 属性会维持 null 为,而且 SelectionChanged 不会引发事件。

0 Answers