You could set a style on the ListBox, which switches ItemTemplate based on the number of items.
<ListBox ItemsSource="{Binding Items}">
    <ListBox.Resources>
        <local:SizeConverter x:Key="SizeConverter"/>
        <DataTemplate x:Key="SmallTemplate"></DataTemplate>
        <DataTemplate x:Key="MediumTemplate"></DataTemplate>
        <DataTemplate x:Key="LargeTemplate"></DataTemplate>
    </ListBox.Resources>
    <ListBox.Style>
        <Style TargetType="ListBox">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Items.Count, Converter={StaticResource SizeConverter}}" Value="Small">
                    <Setter Property="ItemTemplate" Value="{StaticResource SmallTemplate}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Items.Count, Converter={StaticResource SizeConverter}}" Value="Medium">
                    <Setter Property="ItemTemplate" Value="{StaticResource MediumTemplate}"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding Path=Items.Count, Converter={StaticResource SizeConverter}}" Value="Large">
                    <Setter Property="ItemTemplate" Value="{StaticResource LargeTemplate}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ListBox.Style>            
</ListBox>
The SizeConverter would be an IValueConverter which returns a size category based on the incoming count, the convert method could be something like this:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    int count = (int)value;
    if (count < 4) return "Large";
    if (count < 12) return "Medium";            
    return "Small";
}