An ItemsControl
is used to draw a UI for a collection of items.
So to start with, you need your collection of items from the database.
public ObservableCollection<MyItem> MyCollection { get; set; }
To draw this using an ItemsControl, you would use XAML like this :
<ScrollViewer Height="100">
<ItemsControl ItemsSource="{Binding MyCollection}" />
</ScrollViewer>
This will use the default UI for an ItemsControl, which is to loop through each item in the collection, and for each one render a TextBlock with the Text property displaying the .ToString()
of the item.
So what actually renders is something like
<ScrollViewer>
<StackPanel>
<TextBlock /> <!-- DataContext is MyCollection[0] -->
<TextBlock /> <!-- DataContext is MyCollection[1] -->
<TextBlock /> <!-- DataContext is MyCollection[2] -->
</StackPanel>
</ScrollViewer>
The ItemsControl lets you modify different parts of the template though.
For example, to change the <StackPanel>
in the XAML above, you would set the ItemsPanel
property to use a Grid instead.
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
Or to change the TextBlock
to something else, you could change the ItemTemplate
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="175" ...>
<TextBlock Text="{Binding Name}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
This would make your output render something like this
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border Width="175" ...> <!-- DataContext is MyCollection[0] -->
<TextBlock Text="{Binding Name}" />
</Border>
<Border Width="175" ...> <!-- DataContext is MyCollection[1] -->
<TextBlock Text="{Binding Name}" />
</Border>
<Border Width="175" ...> <!-- DataContext is MyCollection[2] -->
<TextBlock Text="{Binding Name}" />
</Border>
</Grid>
</ScrollViewer>
To set Grid.Column, it's actually a bit trickier. An ItemsControl actually wraps each item in a <ContentPresenter>
so each item in the XAML above would actually render more like this :
<ContentPresenter>
<Border Width="175" ...> <!-- DataContext is MyCollection[0] -->
<TextBlock Text="{Binding Name}" />
</Border>
</ContentPresenter>
To set a property like Grid.Column
, it needs to be set on the ContentPresenter
that wraps each item. And that's what the ItemContainerStyle
is used for.
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column"
Value="{Binding ColumnIndex}" />
<Setter Property="Grid.Row"
Value="{Binding RowIndex}" />
</Style>
</ItemsControl.ItemContainerStyle>
So assuming you were binding to
public ObservableCollection<MyItem> MyCollection { get; set; }
and MyItem
looked like this
public class MyItem
{
public int RowIndex { get; set; }
public int ColumnIndex { get; set; }
public string Name { get; set; }
}
Your final XAML might look something like this
<ItemsControl ItemsSource="{Binding MyCollection}">
<!-- ItemsPanelTemplate -->
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Grid.Column"
Value="{Binding ColumnIndex}" />
<Setter Property="Grid.Row"
Value="{Binding RowIndex}" />
</Style>
</ItemsControl.ItemContainerStyle>
<!-- ItemTemplate -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Width="175" ...>
<TextBlock Text="{Binding Name}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
And it would render something like this :
<ScrollViewer>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!-- DataContext is MyCollection[0] -->
<ContentPresenter Grid.Row="{Binding RowIndex}" Grid.Column="{Binding ColumnIndex}">
<Border Width="175" ...>
<TextBlock Text="{Binding Name}" />
</Border>
</ContentPresenter>
<!-- DataContext is MyCollection[1] -->
<ContentPresenter Grid.Row="{Binding RowIndex}" Grid.Column="{Binding ColumnIndex}">
<Border Width="175" ...>
<TextBlock Text="{Binding Name}" />
</Border>
</ContentPresenter>
<!-- DataContext is MyCollection[2] -->
<ContentPresenter Grid.Row="{Binding RowIndex}" Grid.Column="{Binding ColumnIndex}">
<Border Width="175" ...>
<TextBlock Text="{Binding Name}" />
</Border>
</ContentPresenter>
</Grid>
</ScrollViewer>