How to display a "more item" in an ItemsControl when the number of elements is bigger than n?

c#, itemscontrol, wpf

Solution

I have used `CompositeCollection` to solve the problem this enables multiple collections and items to be displayed as a single list. more on CompositeCollection

here is a sample

xaml

<ItemsControl ItemsSource="{Binding Items}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="2" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Resources>
        <DataTemplate DataType="{x:Type sys:Int32}">
            <Border Margin="4"
                    Background="LightSkyBlue">
                <TextBlock Text="{Binding}" FontSize="15"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center" />
            </Border>
        </DataTemplate>
        <DataTemplate DataType="{x:Type sys:String}">
            <Border Margin="4"
                    Background="MediumPurple">
                <TextBlock Text="{Binding}" FontWeight="SemiBold"
                                HorizontalAlignment="Center"
                                VerticalAlignment="Center" />
            </Border>
        </DataTemplate>
    </ItemsControl.Resources>      
</ItemsControl>

note that I have defined data templates for two different types i.e. int and string which will help me render the same accordingly

    public ViewModel()
    {
        IEnumerable<int> originalData = Enumerable.Range(1, 12);
        Items = new CompositeCollection();
        Items.Add(new CollectionContainer() { Collection = originalData.Take(originalData.Count() > 8 ? 7 : 8) });
        if (originalData.Count() > 8)
            Items.Add(originalData.Count() - 7 + " more");
    }

    public CompositeCollection Items { get; set; }

whole idea is to limit the number of elements in the primary collection and add an extra element to the collection of different type eg original list is int and extra is a string

so item control will render all the elements in the collection and we can control the appearance based on the data type

you may also make use of `Attached Properties` or `Converters` to simplify this or perform more sophisticated functions.

result

Problem

I have an `ItemsControl` that displays tiles in a Windows 8 manner with 2 columns and 4 rows. Each tile is clickable and triggers a command that will load the selected item in another view. My problem starts here: my bound `IList<>` can contain more than 8 elements at the time, but must display no more than 8 tiles. What I am trying to achieve is to create a different type of tile (linked to another command) that will appear (ex: using a `Converter`) only when my `IList<>` is bigger than 8. Please check the drawing below to understand my aim. So far I could limit the number of elements retrieved in the `IList<>` container to 7 whenever it is bigger than 8, but adding the "special" 8th element is still a mystery for me.

Original source