Error somewhere not in this code.
You may be confused about VM instances.
This is often the case for beginners.
There may be something wrong with the implementation of SimulationType. You didn't show it.
Here's a complete example of your code demonstrating that multiselect binding works correctly.
using Simplified;
using System;
using System.Collections.ObjectModel;
namespace Core2022.SO.ChaithanyaS
{
public class Item : ViewModelBase
{
private string _title = string.Empty;
public string Title
{
get => _title;
set => Set(ref _title, value ?? string.Empty);
}
private bool _isSelected;
public bool IsSelected
{
get => _isSelected;
set => Set(ref _isSelected, value);
}
}
public class SimulationType : Item
{
private int _count;
public int Count { get => _count; set => Set(ref _count, value); }
}
public class ItemsViewModel : ViewModelBase
{
private static readonly Random random = new Random();
private Item? _selectedItem;
public ObservableCollection<Item> Items { get; } =
new ObservableCollection<Item>()
{
new Item() {Title = "First" },
new SimulationType() { Title = "Yield Simulation", Count = random.Next(5, 15) },
new Item() {Title = "Second" },
new SimulationType() { Title = "HLR Simulation", Count = random.Next(5, 15) },
new SimulationType() { Title = "UnCorr HLR Simulation", Count = random.Next(5, 15)},
new Item() {Title = "Third" }
};
public Item? SelectedItem { get => _selectedItem; set => Set(ref _selectedItem, value); }
}
}
<Window x:Class="Core2022.SO.ChaithanyaS.ItemsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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:local="clr-namespace:Core2022.SO.ChaithanyaS"
mc:Ignorable="d"
Title="ItemsWindow" Height="450" Width="800">
<Window.DataContext>
<local:ItemsViewModel/>
</Window.DataContext>
<UniformGrid Columns="2">
<ListBox Margin="10"
SelectedItem="{Binding SelectedItem}"
ItemsSource="{Binding Items}"
SelectionMode="Multiple">
<FrameworkElement.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<CheckBox Foreground="Red"
Content="{Binding Title}"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:SimulationType}">
<CheckBox Foreground="Green"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}">
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Title"/>
<Binding Path="Count"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</CheckBox>
</DataTemplate>
</FrameworkElement.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<ItemsControl ItemsSource="{Binding Items}" Margin="10"
BorderBrush="Green" BorderThickness="1"
Padding="10">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type local:Item}">
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<TextBlock Foreground="Red"
Text="{Binding Title}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:SimulationType}">
<TextBlock Foreground="Green">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Title"/>
<Binding Path="Count"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataTemplate.Resources>
<Label x:Name="cc" Content="{Binding}" Margin="1" BorderBrush="Gray" BorderThickness="1"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="cc" Property="Background" Value="LightPink"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</UniformGrid>
</Window>
Perhaps you mean that in multi-selection mode, the SelectedItem property always has only the item that was selected first, until it is deselected?
Unfortunately, the implementation of such a task is not easy.
It's better to make a custom AP property and then use it in XAML.
public static class MuliSelectorHelper
{
/// <summary>Returns the value of the IsSelectedItemLast attached property for <paramref name="multiSelector"/>.</summary>
/// <param name="multiSelector"><see cref="DependencyObject"/> whose property value will be returned.</param>
/// <returns><see cref="bool"/> property value.</returns>
public static bool GetIsSelectedItemLast(DependencyObject multiSelector)
{
return (bool)multiSelector.GetValue(IsSelectedItemLastProperty);
}
/// <summary>Sets the value of the IsSelectedItemLast attached property for <paramref name="multiSelector"/>.</summary>
/// <param name="multiSelector"><see cref="MultiSelector"/> whose property value will be returned.</param>
/// <param name="value"><see cref="bool"/> value for property.</param>
public static void SetIsSelectedItemLast(DependencyObject multiSelector, bool value)
{
multiSelector.SetValue(IsSelectedItemLastProperty, value);
}
/// <summary><see cref="DependencyProperty"/> for methods <see cref="GetIsSelectedItemLast(MultiSelector)"/>
/// and <see cref="SetIsSelectedItemLast(MultiSelector, bool)"/>.</summary>
public static readonly DependencyProperty IsSelectedItemLastProperty =
DependencyProperty.RegisterAttached(
nameof(GetIsSelectedItemLast).Substring(3),
typeof(bool),
typeof(MuliSelectorHelper),
new PropertyMetadata(false, OnIsSelectedItemLastChanged));
private static void OnIsSelectedItemLastChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is not Selector selector || selector.GetValue(ListBox.SelectedItemsProperty) is not IList list)
{
throw new NotImplementedException("Implemented only types that derive from Selector and that use the ListBox.SelectedItems dependency property.");
}
if (Equals(e.NewValue, true))
{
selector.SelectionChanged += OnSelectionChanged;
}
else
{
selector.SelectionChanged -= OnSelectionChanged;
}
}
private static async void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count == 0)
return;
Selector selector = (Selector)sender;
IList selectedItems = (IList)selector.GetValue(ListBox.SelectedItemsProperty);
if (selectedItems.Count != e.AddedItems.Count && !Equals(selectedItems[0], e.AddedItems[0]))
{
selector.SelectionChanged -= OnSelectionChanged;
int beginIndex = selectedItems.Count - e.AddedItems.Count;
var selectedItemsArray = new object[selectedItems.Count];
selectedItems.CopyTo(selectedItemsArray, 0);
selectedItems.Clear();
await selector.Dispatcher.BeginInvoke(() =>
{
for (int i = selectedItemsArray.Length-1; i >= beginIndex; i--)
{
selectedItems.Add(selectedItemsArray[i]);
}
for (int i = 0; i < beginIndex; i++)
{
selectedItems.Add(selectedItemsArray[i]);
}
});
selector.SelectionChanged += OnSelectionChanged;
}
}
}
<UniformGrid Columns="2">
<ListBox Margin="10"
SelectedItem="{Binding SelectedItem}"
ItemsSource="{Binding Items}"
SelectionMode="Multiple"
local:MuliSelectorHelper.IsSelectedItemLast="true">
<FrameworkElement.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<CheckBox Foreground="Red"
Content="{Binding Title}"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:SimulationType}">
<CheckBox Foreground="Green"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}">
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Title"/>
<Binding Path="Count"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</CheckBox>
</DataTemplate>
</FrameworkElement.Resources>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected" Value="{Binding Mode=TwoWay, Path=IsSelected}"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
<ContentControl Content="{Binding SelectedItem}">
<ContentControl.ContentTemplate>
<DataTemplate DataType="{x:Type local:Item}">
<DataTemplate.Resources>
<DataTemplate DataType="{x:Type local:Item}">
<TextBlock Foreground="Red"
Text="{Binding Title}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:SimulationType}">
<TextBlock Foreground="Green">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Title"/>
<Binding Path="Count"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataTemplate.Resources>
<Label x:Name="cc" Content="{Binding}" Margin="1" BorderBrush="Gray" BorderThickness="1"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="True">
<Setter TargetName="cc" Property="Background" Value="LightPink"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</UniformGrid>