Search code examples
xamlmvvmgroupingtabcontrolcollectionviewsource

CollectionViewSource Grouping "All Items"


I have created a CollectionViewSource as follows:

<CollectionViewSource x:Key="MyGrouping" Source="{Binding MyCollection}">
    <CollectionViewSource.SortDescriptions>
        <componentModel:SortDescription PropertyName="Name"/>
    </CollectionViewSource.SortDescriptions>
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="Type"/>
    </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

I then define a TabControl as follows:

<TabControl ItemsSource="{Binding Groups, Source={StaticResource MyGrouping}}">
    <TabControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"/>
        </DataTemplate>
    </TabControl.ItemTemplate>
    <TabControl.ContentTemplate>
        <DataTemplate>
            <DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False">
                <DataGrid.Resources>

.....

All of the grouping works perfectly. However, I wanted to add an additional Tab that contains ALL of the items (ungrouped).

Is there a simple mvvm approach to doing this? Any help would be greatly appreciated.


Solution

  • A basic idea is to create custom ListCollectionView with customized CollectionViewGroup. Below is the example.

    public class CustomGroupListCollectionView : ListCollectionView
    {
        private readonly CustomGroup _allGroup;
    
        public CustomGroupListCollectionView(IList list)
            : base(list)
        {
            _allGroup = new CustomGroup("All");
            foreach (var item in list)
            {
                _allGroup.AddItem(item);
            }
        }
    
        public override ReadOnlyObservableCollection<object> Groups
        {
            get
            {
                var group = new ObservableCollection<object>(base.Groups.ToList());
                group.Add(_allGroup);
                return new ReadOnlyObservableCollection<object>(group);
            }
        }
    }
    
    public class CustomGroup : CollectionViewGroup
    {
        public CustomGroup(object name)
            : base(name)
        {
        }
    
        public void AddItem(object item)
        {
            ProtectedItems.Add(item);
        }
    
        public override bool IsBottomLevel
        {
            get { return true; }
        }
    }