CollectionView 項目の選択を構成する

Browse sample. サンプルを参照する

.NET マルチプラットフォーム アプリ UI (.NET MAUI) CollectionView は、項目の選択を制御する次のプロパティを定義します。

  • SelectionMode 型の SelectionMode。選択モードです。
  • object 型の SelectedItem。リストで選択されている項目です。 このプロパティでは、デフォルトのバインディング モードは TwoWay で、項目が選択されていない場合は null 値になります。
  • IList<object> 型の SelectedItems。リストで選択されている複数の項目です。 このプロパティでは、デフォルトのバインディング モードは OneWay で、項目が選択されていない場合は null 値になります。
  • ICommand 型の SelectionChangedCommand。選択した項目が変更されたときに実行されます。
  • SelectionChangedCommandParameter: object 型、SelectionChangedCommand に渡されるパラメーター。

これらのプロパティはすべて、BindableProperty オブジェクトを基盤としています。つまり、プロパティはデータ バインディングの対象にすることができます。

デフォルトでは、CollectionView の選択は無効になっています。 ただし、SelectionMode プロパティ値を SelectionMode 列挙型メンバーのいずれかに設定することで、この動作を変更できます。

  • None – 項目が選択できないことを示します。 これが既定値です。
  • Single – 選択した項目が強調表示された状態で、1 つの項目を選択できることを示します。
  • Multiple – 選択した項目が強調表示された状態で、複数の項目を選択できることを示します。

ユーザーがリストから項目を選択する、またはアプリケーションがプロパティを設定すると、CollectionView は、SelectedItem プロパティが変更されたときに発生する SelectionChanged イベントを定義します。 さらに、このイベントは、SelectedItems プロパティが変更されたときにも発生します。 SelectionChanged イベントに付随する SelectionChangedEventArgs オブジェクトには、IReadOnlyList<object> 型のプロパティが 2 つあります。

  • PreviousSelection – 選択が変更される前に選択された項目のリストです。
  • CurrentSelection – 選択が変更された後に選択された項目のリストです。

さらに、CollectionView には、選択した項目のリストで SelectedItems プロパティを更新する UpdateSelectedItems メソッドがあり、変更通知を 1 つだけ発行します。

単一選択

SelectionMode プロパティが Single に設定されている場合、CollectionView で 1 つの項目を選択できます。 項目が選択されると、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;
    ...
}

重要

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;

このコード例では、SelectionChanged イベントが発生したときに OnCollectionViewSelectionChanged イベント ハンドラーが実行されます。イベント ハンドラーは、以前に選択した項目と現在選択している項目を取得します。

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");

Note

SelectedItem プロパティの既定のバインド モードは TwoWay です。

SelectedItem プロパティ データは、Monkey 型の接続ビュー モデルの SelectedMonkey プロパティにバインドされます。 既定では、バインドが使用され、TwoWay ユーザーが選択した項目を変更すると、プロパティの SelectedMonkey 値が選択した Monkey オブジェクトに設定されます。 SelectedMonkey プロパティは MonkeysViewModel クラスで定義され、Monkeys コレクション内の 4 番目の項目に設定されます。

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 が表示されると、リストの 4 番目の項目が事前に選択されていることになります。

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");

Note

SelectedItems プロパティの既定のバインド モードは OneWay です。

SelectedItems プロパティ データは、ObservableCollection<object> 型の接続ビュー モデルの SelectedMonkeys プロパティにバインドされます。 SelectedMonkeys プロパティは MonkeysViewModel クラスで定義され、Monkeys コレクション内の 2 番目、4 番目、5 番目の項目に設定されます。

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 が表示されると、リスト内の 2 番目、4 番目、5 番目の項目が事前に選択されていることになります。

Screenshot of a CollectionView vertical list with multiple preselection.

選択解除

SelectedItem プロパティと SelectedItems プロパティは、それらのプロパティまたはバインド先のオブジェクトを 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>

重要

SelectedVisualState を含む Style には、DataTemplate のルート要素の型である TargetType プロパティ値が必要です。これは 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);

この例では、ItemTemplate のルート要素が Grid であるため、Style.TargetType プロパティの値は Grid に設定されています。 SelectedVisualState は、CollectionView 内の項目が選択されたとき、その項目の BackgroundColorLightSkyBlue に設定します。

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 イベントは発生しません。

Note

項目が選択されていて、SelectionMode プロパティが Single から None に変更されると、SelectedItem プロパティが null に設定され、CurrentSelection プロパティが空の SelectionChanged イベントが発生します。