[xamarin][C#][ListView]選択中のViewCellの背景色を変えるのが物凄いめんどくさかった

Yutaka_kun
LSC PSD
Published in
7 min readFeb 4, 2021

ViewCellは選択するものだから、選択中のセルの背景色ぐらいxamarinでささっと設定できるでしょ??って思ってたらほんと痛い目にあいました。
一応やり方はネットにのっていて、<ListView.Behavior>を使ったり、IValueConverterを使ったりすればできるらしいですが、初心者の僕には訳わからんかったです。激闘の末、それ以外のやり方でできたのでここにのせておきます。

いろいろ省略している部分もあるので、そのまんまコピペだとうまく動かないかもしれません。でも順を追って読んでいけばどの様な手順でコードを組んでいけばいいか想像はつくはずです。(上級者からみたら突っ込みどころは満載かも)(突っ込んでいただける人はコメントまで、、)

*2021/2/4 更新

MainPage.xaml

<Grid>
<ListView SelectedItem="{Binding SelectedItem}"
ItemsSource="{Binding Items}"
BackgroundColor="Silver">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid BackgroundColor="{Binding CellColor}>
//何か書く
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>

ListViewのSelectedItem,ItemsSourceはそれぞれViewModelのSelectedItemプロパティ,Itemsプロパティとバインドさせます
ViewCellの中のGridのBackgroundColorは(後述する)Itemクラスの中のCellColorプロパティと直接バインドさせます

ViewModel.cs

public ObservableCollection<Item> Items { get => Items; }
public object SelectedItem { get => SelectedItem; set => SelectedItem = value; }

ViewModelのItemsプロパティ,SelectedItemプロパティはModelのItemsプロパティ,SelectedItemプロパティとそれぞれバインドさせます(ここはViewとModelをつないでいるだけですね)

Model.cs

private ObservableCollection<Item> _items = null;
public ObservableCollection<Item> Items
{
get { return _detecteditems; }
set { _detecteditems = value;
RaisePropertyChanged(nameof(Items)); }
}
private object _selecteditem;
public object SelectedItem
{
get{ return _selecteditem; }
set{
//ここマジ重要(後述)
if(_selecteditem != null && _selecteditem is Item item)
{
item.IsSelect = false;
}
_selecteditem = value;
if(_selecteditem != null && _selecteditem is Item item1)
{
item1.IsSelect = true;
}
RaisePropertyChanged(nameof(SelectedItem));}

//
}
//CommandでListmake関数を呼び出す
public void Listmake()
{
Items = null;
var itemlist = new ObservableCollection<Item>();
Items = itemlist;
var item_0 = new Item();
var item_1 = new Item();
itemlist.Add(item_0);
itemlist.Add(item_1);
}

xamlのコマンドかなにかでListmake関数を発動させ、Items SourceとバインドしているItemsの中にItemクラスがいくつか入ったitemlistをぶちこみます。

Item.cs

private bool _isselect = false;
public bool IsSelect
{
get { return _isselect; }
set { _isselect = value;
RaisePropertyChanged(nameof(IsSelect));
Change_BackgroundColor(); }
}
private Color _cellcolor = Color.Silver;
public Color CellColor
{
get { return _cellcolor; }
set { _cellcolor = value;
RaisePropertyChanged(nameof(CellColor)); }
}
public void Change_BackgroundColor()
{
if (IsSelect == true)
{
CellColor = Color.White;
}
else
CellColor = Color.Silver;
}

ItemクラスはIsSelectプロパティ、CellColorプロパティを持っていて、IsSelectのsetが走った時は Change_BackgroundColor関数が呼び出されるようにしておきます。

ここマジ重要

の部分の説明

if(_selecteditem != null && _selecteditem is Item item)
{
item.IsSelect = false;
}
_selecteditem = value;
if(_selecteditem != null && _selecteditem is Item item1)
{
item1.IsSelect = true;
}
RaisePropertyChanged(nameof(SelectedItem));}
//

① SelectedItemに変更があった場合setの中が走る

② 新しく選択されたItemクラスが_selecteditem = valueで代入される前に、以前選択されていたItemクラスのIsSelectプロパティをfalseに変える

③ 新しく選択されたItemクラスが_selecteditem = valueで代入される

④新しく選択されたItemクラスのIsSelectプロパティをtrueに変える

ここまでくれば説明は不要ですね、、、

IsSelectのプロパティに変更があった場合IsSelectプロパティのsetが走りますから、Change_BackgroundColor関数が呼び出されます。
Itemクラスが持ってるIsSelectプロパティのtrue/falseによってCellColorプロパティに変更がかかります。
GridのBackgroundColorがCellColorプロパティとバインドしていますので、これでViewCellの背景色が変わると言うわけです。

--

--

Yutaka_kun
LSC PSD
Editor for

Microbiology technician,Machine learning engineer(beginner)