Avaloniaという、C#でマルチプラットフォームなGUIアプリを作れるフレームワークを試していたところ苦戦したので書きます
正解
~
<ListBox
ItemsSource="{Binding Items}"
SelectionMode="Multiple"
SelectedItems="{Binding SelectedItems}">
省略
</ListBox>
~
ListBoxでは、SelectionModeプロパティをMultipleにすることで、画像のように項目をCtrl+クリックで複数選択できるようになります
また、SelectedItemsプロパティから、選択している項目をすべてIListで取得することができます
私はObservableCollectionを使いました
//選択項目だけが入るコレクション
public ObservableCollection<ItemViewModel> SelectedItems { get; } = new();
//項目をぜんぶ入れるコレクション
public ObservableCollection<ItemViewModel> Items { get; } = new();
//あとはforeachとかでSelectedItemsを使えばオッケー
これだけです
また、上記の例ではなにも選択していない状態でもNullになりません
なにに苦戦したんだよ
ListBoxには、選択項目を1つだけ取得できるSelectedItemというプロパティもあります
~
<ListBox
ItemsSource="{Binding Items}"
SelectionMode="Multiple"
SelectedItem="{Binding SelectedItem}">
省略
</ListBox>
~
//選択した項目プロパティの実部
private ItemViewModel? _selectedItem;
//項目をぜんぶ入れるコレクション
public ObservableCollection<ItemViewModel> Items { get; } = new();
public ItemViewModel? SelectedItem
{
get => _selectedItem;
set => this.RaiseAndSetIfChanged(ref _selectedItem, value);
}
SelectedItemでは、このように選択項目が入るプロパティをViewModelに用意してあげれば、初期化せずとも選択項目が格納されます(ただし未選択ではNullになる)
このノリで
private ObservableCollection<ItemViewModel> _selectedItems;
public ObservableCollection<ItemViewModel> Items { get; } = new();
public ObservableCollection<ItemViewModel> SelectedItems
{
get => _selectedItems;
set => this.RaiseAndSetIfChanged(ref _selectedItems, value);
}
ObservableCollectionのプロパティを用意して作ろうとしましたが、_selectedItemsの実体がないのでNullになってしまいました
とても初歩的なミスでしたが、これでもXAMLとのバインドはできてビルドも通り、リストをぽちぽちしても何も起きないため、複数選択を実際に取得するまで気が付きませんでした
このバインドは結構ゆるくて、SelectedItemsもstring型のプロパティにバインドしてもビルドが通ります。なんでだよ!
こんな初心者の備忘録ですが、誰かの役に立ちましたら幸いです
参考資料
ListBoxのSelectedItemsのリファレンス
ListBoxのドキュメント