Search code examples
wpfbindingstylesviewbox

WPF: Change the style of a ViewBox depending upon the amount of data


I have a WPF app that has a ViewBox to display the items in my collection, diplaying a 2-column grid for my results.

What I'd like to do is, depending on the number of items in my collection, change the number of columns. E.g if there are < 10 items in the list, then show them in just 1 column; If there are 10 items in my list, then show them in 2 columns; If there are 20 items in my list, then show 3 columns.

Here's what I have at present:

<Viewbox>
   <ItemsControl ItemsSource="{Binding myCollection}" Style="{DynamicResource myStyle}" />
</Viewbox>

Here's what myStyle currently defines:

<Style x:Key="myStyle" TargetType="{x:Type ItemsControl}">
   <Setter Property=ItemsControl.ItemsPanel">
      <Setter.Value>
         <ItemsPanelTemplate>
           <UniformGrid Columns="2" />
         </ItemsPanelTemplate>
      </Setter.Value>
   </Setter>
</Style>

How can I make this code work to the above requirement? Thanks.


Solution

  • You could bind the Columns property to the number of items and use an appropriate IValueConverter to determine the number of columns, like so:

    <UniformGrid Columns="{Binding Items.Count, Converter={local:ItemsToColumnConverter}}" />
    

    Note that you might need to add a RelativeSource to this Binding in order to make it work.

    And an IValueConverter similar to that:

    public class ItemsToColumnConverter : IValueConverter
    {
        // ...
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int numItems = (int)value;
            if (numItems < 10)
                return 1;
            else if (numItems < 20)
                return 2;
            else if (numItems < 30)
                return 3;
            else
                return numItems / 10;
        }
    
        public object ConvertBack(...)
        {
            throw new NotSupportedException();
        }
    }
    

    Of course, you could also make that converter use another math logic which avoids all the if-elseif-else stuff.