I am trying to show MultiSelectComboBox in Datagrid cell but even though combo box works alone, it shows empty if I put it inside the data grid.
I think it is related to <UserControl.Resources> vs <DataGrid.Resources> but I couldn't find a fix.
You can find the solution from here.
My Model:
public class Blocks : BaseViewModel
{
private bool _isSelected;
private int _id;
private string _name;
public Blocks(string name)
{
_name = name;
}
public bool IsSelected
{
get => _isSelected;
set
{
if (_isSelected == value) return;
_isSelected = value;
OnPropertyChanged();
}
}
public int ID
{
get => _id;
set
{
if (_id == value) return;
_id = value;
OnPropertyChanged();
// multicombox default filtreleme için name kullanıyor
_name = value.ToString();
}
}
public string Name
{
get => _name;
set
{
if (_name != null && string.Compare(_name, value, StringComparison.InvariantCulture) == 0)
{
return;
}
_name = value;
OnPropertyChanged();
}
}
public override string ToString()
{
return ID.ToString();
}
}
My ViewModel:
public class ListItemsViewModel : BaseViewModel { private ObservableCollection _routes;
public ObservableCollection<int> Routes
{
get => _routes ?? (_routes = new ObservableCollection<int>());
set
{
_routes = value;
OnPropertyChanged();
}
}
// multi combo box
private ICommand _selectedStatusItemsChangedCommand;
private ObservableCollection<Blocks> _includedBlocks;
private ObservableCollection<Blocks> _selectedBlocks;
public ObservableCollection<Blocks> IncludedBlocks
{
get => _includedBlocks ?? (_includedBlocks = new ObservableCollection<Blocks>());
set
{
_includedBlocks = value;
OnPropertyChanged();
}
}
public ObservableCollection<Blocks> SelectedBlocks
{
get => _selectedBlocks ?? (_selectedBlocks = new ObservableCollection<Blocks>());
set
{
_selectedBlocks = value;
OnPropertyChanged();
}
}
public ICommand SelectedItemsChangedCommand
=> _selectedStatusItemsChangedCommand ?? (_selectedStatusItemsChangedCommand = new CommandHandler(SelectedItemsChanged));
public ListItemsViewModel(ObservableCollection<Blocks> list, ObservableCollection<int> ints)
{
_includedBlocks = list;
_routes = ints;
}
// Multi select combo box
public int SelectedStatusItemsCount { get; set; }
private void UpdateSelectedStatusItemsCount(int count)
{
SelectedStatusItemsCount = count;
OnPropertyChanged();
}
private void SelectedItemsChanged(object parameter)
{
if (parameter is SelectedItemsChangedEventArgs args)
{
foreach (var virtualRailBlock in _includedBlocks)
{
var selectedItemIndex = args.Selected.Cast<Blocks>().ToList().IndexOf(virtualRailBlock);
virtualRailBlock.IsSelected = selectedItemIndex > -1;
}
UpdateSelectedStatusItemsCount(args.Selected.Count);
}
}
}
My View:
<UserControl x:Class="MultiSelectControlCodes.View.ListItemsView"
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:sdl="http://schemas.sdl.com/xaml"
xmlns:viewModel="clr-namespace:MultiSelectControlCodes.ViewModel"
xmlns:model="clr-namespace:MultiSelectControlCodes.Model"
mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="400"
d:DataContext="{d:DesignInstance viewModel:ListItemsViewModel}">
<Grid>
<DataGrid
ItemsSource="{Binding Routes}"
SelectionUnit="FullRow"
SelectionMode="Extended"
AutoGenerateColumns="False"
IsReadOnly="False"
CanUserAddRows="True"
CanUserDeleteRows="True">
<DataGrid.Resources>
<DataTemplate x:Key="MultiSelectComboBox.Dropdown.ListBox.ItemTemplate" DataType="Block">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" VerticalAlignment="Center" Text="{Binding Path=Name}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="MultiSelectComboBox.SelectedItems.ItemTemplate" DataType="Block">
<StackPanel Orientation="Horizontal" Margin="0,-4">
<TextBlock VerticalAlignment="Center" Text="{Binding Path=Name}" Margin="2,0" />
</StackPanel>
</DataTemplate>
</DataGrid.Resources>
<DataGrid.Columns >
<DataGridTemplateColumn Header="Routes" Width="100">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<sdl:MultiSelectComboBox
Margin="2"
VerticalAlignment="Top"
Height="50"
IsEditable="true"
SelectionMode="Multiple"
SelectedItems="{Binding SelectedBlocks}"
ItemsSource="{Binding IncludedBlocks}"
SelectedItemTemplate="{StaticResource MultiSelectComboBox.SelectedItems.ItemTemplate}"
DropdownItemTemplate="{StaticResource MultiSelectComboBox.Dropdown.ListBox.ItemTemplate}"
sdl:SelectedItemsChangedBehaviour.SelectedItemsChanged="{Binding SelectedItemsChangedCommand}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</Grid>
</UserControl>
Resulting window:
Working View:
<UserControl x:Class="MultiSelectControlCodes.View.ListItemsView"
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:sdl="http://schemas.sdl.com/xaml"
xmlns:viewModel="clr-namespace:MultiSelectControlCodes.ViewModel"
xmlns:model="clr-namespace:MultiSelectControlCodes.Model"
mc:Ignorable="d" d:DesignHeight="200" d:DesignWidth="400"
d:DataContext="{d:DesignInstance viewModel:ListItemsViewModel}">
<UserControl.Resources>
<DataTemplate x:Key="MultiSelectComboBox.Dropdown.ListBox.ItemTemplate" DataType="Block">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" VerticalAlignment="Center" Text="{Binding Path=Name}"/>
</Grid>
</DataTemplate>
<DataTemplate x:Key="MultiSelectComboBox.SelectedItems.ItemTemplate" DataType="Block">
<StackPanel Orientation="Horizontal" Margin="0,-4">
<TextBlock VerticalAlignment="Center" Text="{Binding Path=Name}" Margin="2,0" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid>
<sdl:MultiSelectComboBox
Margin="2"
VerticalAlignment="Top"
Height="50"
IsEditable="true"
SelectionMode="Multiple"
SelectedItems="{Binding SelectedBlocks}"
ItemsSource="{Binding IncludedBlocks}"
SelectedItemTemplate="{StaticResource MultiSelectComboBox.SelectedItems.ItemTemplate}"
DropdownItemTemplate="{StaticResource MultiSelectComboBox.Dropdown.ListBox.ItemTemplate}"
sdl:SelectedItemsChangedBehaviour.SelectedItemsChanged="{Binding SelectedItemsChangedCommand}"/>
</Grid>
</UserControl>
Working Result: