0

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

1 Answer 1

1

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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.