You can do this by using nested ItemsControls
bound to a PagedCollectionView.
Say I have a datasource - MyItems
- with fields: Category
, Section
and Option
. I can create a PagedCollectionView
from an IEnumerable(of MyItems)
and tell it which fields to group by.
Dim original As IEnumerable(Of MyItems) = GetMyItems()
Dim pcv = New PagedCollectionView(original)
pcv.GroupDescriptions.Add(New PropertyGroupDescription("Category"))
pcv.GroupDescriptions.Add(New PropertyGroupDescription("Section"))
Then I bind my first ItemsControl
to the PagedCollectionView
hisMyItems.ItemsSource = pcv.Groups
The PCV
creates a nested hierachy like:
-Name
-Items
where Name
is the value in the grouped field and Items
contains the rows/objects in that grouping. I guess you could also create the PCV in xaml if you prefer.
The xaml would look something like:
<controls:HeaderedItemsControl x:Name="hisMyItems" Header="{Binding Name}" ItemsSource="{Binding Items}" >
<controls:HeaderedItemsControl.ItemTemplate>
<DataTemplate>
<controls:HeaderedItemsControl Header="{Binding Name}" ItemsSource="{Binding Items}" ItemsPanel="{StaticResource ItemsPanelTemplate1}" >
<controls:HeaderedItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Option}" />
</DataTemplate>
</controls:HeaderedItemsControl.ItemTemplate>
</controls:HeaderedItemsControl>
</DataTemplate>
</controls:HeaderedItemsControl.ItemTemplate>
</controls:HeaderedItemsControl>
I hope that makes sense. I have tried to simplify things from my actual app but I could have made some mistakes in copying it over. Obviously you could use normal ItemsControls or other controls too and customize with templates etc.
You might want to take a look at the ItemsPanel property:
Gets or sets the template that defines the panel that controls the layout of items.
Example:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
And you can set it in a Style as follows:
<Style TargetType="ItemsControl">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
Best Answer
ItemsControl
is conceptually a control that houses items. Try to simply think of this control as a holder for zero or more objects.ItemsPresenter
is a bit tougher to explain, but this is part of theItemsControl
template that will define where the items are placed within it. Your ItemsControl's template can be anything you like, say a Grid with some pretty pictures around it, inside this template, you would place theItemsPresenter
where ever you want your items to be, say right in the middle of your grid. (this example is taken from msdn and simplified for ease of reading)The
ItemsPanel
is the panel (or container) that controls the layout of the items in your ItemsControl. So if you want your items that you have added to your ItemsControl to display in a horizotal way, then yor items panel could simply be a StackPanel with its Orientation property set to Horizontal.This all make sense?