I have a strange layout for an ItemsControl.
I have a 4x6 grid with the following pattern:
1 2 3 4
13 14 15 16
5 6 7 8
17 18 19 20
9 10 11 12
21 22 23 24
Is there an easy way to do this? should I be using 6 Items Controls and take "sections" of my list? is there a good way to do this? What about notification?
It's important to note that I may, or may not, have all 24 entries present, but the layout needs to be maintained (think of it like filled slots on a bingo card or something)
Edit:
Ideally, I'd like to be able to take a list, and do some fun sorting/padding type stuff off properties on the items in the list.
for instance, if I have an ObservableCollection with a few units, and Unit has a property "Index", I'd like to have a view consumable Collection generated that automatically uses Index to make a padded list. I guess an observable dictionary could work, but that seems gross. Maybe a new custom layout panel is in order?
There is a clever way of doing this in pure XAML using a custom template for your ItemsControl. It's easiest if all your "cards" have a fixed size, say 100x100:
<!-- Wrap each card in a decorator twice as high as the card cell -->
<DataTemplate x:Key="ItemInDoubleHighBox">
<Decorator Width="100" Height="200">
<Decorator Width="100" Height="100" ClipToBounds="True">
<ContentPresenter />
</Decorator>
</Decorator>
</DataTemplate>
<!-- Define a template for use with WrapPanel -->
<ItemsPanelTemplate x:Key="WrapPanelTemplate">
<WrapPanel />
</ItemsPanelTemplate>
<!-- Now the actual ItemsControl template -->
<ControlTemplate TargetType="ItemsControl">
<Grid Width="600" Height="600" ClipToBounds="True">
<!-- Items 1 to 12 -->
<ItemsControl ItemsSource="{TemplateBinding ItemsSource}"
ItemsPanel="{StaticResource WrapPanelTemplate}"
ItemTemplate="{StaticResource ItemInDoubleHighBox}" />
<!-- Items 13 to 24 -->
<ItemsControl ItemsSource="{TemplateBinding ItemsSource}"
ItemsPanel="{StaticResource WrapPanelTemplate}"
ItemTemplate="{StaticResource ItemInDoubleHighBox}"
RenderTransform="1 0 0 1 0 -500" />
</Grid>
</ControlTemplate>
How it works: The DataTemplate causes the items to be "double-spaced" with only 1-12 visible, and the RenderTransform on the second ItemsControl makes items 13-24, which are also "double-spaced" appear in the spaces between the first rows of items.
Note: You can make the height and width data-bindable, but it takes more XAML. Just add ScaleTransforms everywhere "200", "500" or "600" appears in the XAML. For example, to deal with the "200" you can set a scale transform on the inner decorator with ScaleY="0.5" and on each ItemsControl with ScaleY="2". Now the outer decorator's height will be 100, which can be data-bound. The other constants can be dealt with via similar pre- and post- scaling of the content. And because WPF combines all the transforms before rendering anyway, the extra transforms will cost basically nothing.