I want to do the same thing as in question How to bind ListBoxItem.IsSelected to boolean data property but using Avalonia instead of WPF.
Given this ViewModel (MainViewModel.cs
)
using System.Collections.Generic;
using CommunityToolkit.Mvvm.ComponentModel;
namespace AvaloniaAskOverflow.ViewModels;
public partial class MainViewModel : ViewModelBase
{
private List<Item> items= new()
{
new ("Item 1", false),
new ("Item 2", true),
new ("Item 3", false),
new ("Item 4", true)
};
public List<Item> Items => items;
}
public class Item: ObservableObject
{
string text;
public string Text { get => text; set => SetProperty(ref text, value); }
bool isSelected;
public bool IsSelected { get => isSelected; set => SetProperty(ref isSelected, value); }
public Item(string text, bool isSelected)
{
this.text = text;
this.isSelected = isSelected;
}
}
I got as far as this (MainView.axaml
)
<UserControl xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:AvaloniaAskOverflow.ViewModels"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="AvaloniaAskOverflow.Views.MainView"
x:DataType="vm:MainViewModel">
<Design.DataContext>
<!-- This only sets the DataContext for the previewer in an IDE,
to set the actual DataContext for runtime, set the DataContext property in code (look at App.axaml.cs) -->
<vm:MainViewModel />
</Design.DataContext>
<ListBox
SelectionMode="Multiple,Toggle"
ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerTheme>
<Style Selector="ListBoxItem">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerTheme>
</ListBox>
</UserControl>
Notes:
ListBox.ItemContainerStyle
in Avalonia, the equivalent is ListBox.ItemContainerTheme
according to https://github.com/AvaloniaUI/Avalonia/discussions/10018)but the compiler replies with this error:
Unable to resolve property or method of name 'IsSelected' on type 'AvaloniaAskOverflow.ViewModels.MainViewModel'. línea 24, posición 35.
Obviously, it is trying to find IsSelected
in MainViewModel
class instead of using Item.IsSelected
.
So, how I bind the IsSelected
property of each ListBoxItem
to the corresponding Item.IsSelected
?
It should be easy as in WPF, but obviously I'm missing something.
Tried Clemens' suggestion, but to no avail. Without ListBox.Styles
everything is ok:
but as soon as I complete the code:
Put the ListBoxItem Style into <ListBox.Styles>
:
<ListBox SelectionMode="Multiple,Toggle"
ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Text}" />
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.Styles>
</ListBox>
Or shorter:
<ListBox SelectionMode="Multiple,Toggle"
ItemsSource="{Binding Items}"
DisplayMemberBinding="{Binding Text}">
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.Styles>
</ListBox>
In case you are using Compiled Bindings, add x:DataType="vm:Item"
to the Style:
<ListBox SelectionMode="Multiple,Toggle"
ItemsSource="{Binding Items}"
DisplayMemberBinding="{Binding Text}">
<ListBox.Styles>
<Style Selector="ListBoxItem" x:DataType="vm:Item">
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}"/>
</Style>
</ListBox.Styles>
</ListBox>