I have three collections like so:
IReadOnlyList<Info> ListA = {'1A', '1B'}
IReadOnlyList<Info> ListB = {'2A', '2B'}
IReadOnlyList<Info> ListC = {'3A', '3B'}
I am trying to group them, add a custom header to each and show then in a ListView. I tried doing this:
<ListView ItemsSource="{DynamicResource FullCollection}">
<ListView.Resources>
<CollectionViewSource x:Key="CollectionA" Source="{Binding CollectionA}" />
<CollectionViewSource x:Key="CollectionB" Source="{Binding CollectionB}" />
<CollectionViewSource x:Key="CollectionC" Source="{Binding CollectionC}" />
<CompositeCollection x:Key="FullCollection">
<ListViewItem IsEnabled="False">Header_A</ListViewItem>
<CollectionContainer Collection="{Binding Source={StaticResource CollectionA}}" />
<ListViewItem IsEnabled="False">Header_B</ListViewItem>
<CollectionContainer Collection="{Binding Source={StaticResource CollectionB}}" />
<ListViewItem IsEnabled="False">Header_C</ListViewItem>
<CollectionContainer Collection="{Binding Source={StaticResource CollectionC}}" />
</CompositeCollection>
</ListView.Resources>
</ListView>
...
Then i created three seperate ICollectionView objects in viewmodel (CollectionA, CollectionB, CollectionC from ListA, ListB, ListC recpectively) like so:
ICollectionView _collectionA= null;
public ICollectionView CollectionA //from ListA
{
get
{
if (_collectionA== null)
{
_collectionA = CollectionViewSource.GetDefaultView(ListA); //original list
PropertyGroupDescription groupDescription = new PropertyGroupDescription("Header_A");
_collectionA.GroupDescriptions.Add(groupDescription);
}
return _collectionA;
}
}
...
Somehow i am not able to get what I want , what am i doing wrong here!?
How can i group them with custom headers (& expanders) and show then in my ListView, like this:
^ Header_A
--1A
--1B
^ Header_B
--2A
--2B
^ Header_C
--3A
--3B
You should create a view model with an additional property for the group header:
public class InfoViewModel
{
public string Category { get; set; }
public string Name { get; set; }
}
You would then translate your current Info
objects to InfoViewModels
and group by the new property, e.g.:
var fullSourceCollection = ListA.Select(x => new InfoViewModel() { Category = "Header_A", Name = x.Name })
.Merge(ListB.Select(x => new InfoViewModel() { Category = "Header_B", Name = x.Name })
.Merge(ListC.Select(x => new InfoViewModel() { Category = "Header_C", Name = x.Name })
.ToArray();
...
PropertyGroupDescription groupDescription = new PropertyGroupDescription(nameof(InfoViewModel.Category));
...
Finally, you should define a group style in the view:
<ListView ...>
<ListView.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock FontWeight="Bold" FontSize="14" Text="{Binding Name}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>