As to your first question, this is probably the pattern you're looking for:
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<Button Grid.Row="1" Grid.Column="2">R1C2</Button>
<Button Grid.Row="2" Grid.Column="1">R2C1</Button>
<Button Grid.Row="0" Grid.Column="0">R0C0</Button>
</ItemsControl>
In a real application, you'd set the ItemsControl.ItemsSource
to a Binding
whose source is a collection of objects, and then create a DataTemplate
like:
<DataTemplate DataType="{x:Type MyObject}">
<Rectangle Grid.Row="{Binding Row}" Grid.Column="{Binding Column}">
<!-- other visuals go here -->
</Rectangle>
</DataTemplate>
As far as organizing the code into separate files goes: you should consider creating a UserControl
for displaying the object, instead of a DataTemplate
. It's no more difficult to create one than the other, and UserControl
s are classes that live in their own XAML files and can be instantiated in XAML, like any other object, by their name.
Depending on your design, you might separate out the grid positioning from the actual visual presentation of the object, so that you can reuse the presentation elsewhere. That's probably how I'd approach it. After creating a UserControl
for my object, I'd create a DataTemplate
in Grid.Resources
(since it's describing how that specific Grid
should display the objects) like this:
<DataTemplate DataType="{x:Type MyObject}">
<DockPanel Grid.Row="{Binding Row}" Grid.Column="{Binding Column}">
<local:MyObjectUserControl DataContext="{Binding}"/>
</DockPanel>
</DataTemplate>
It's also possible to organize XAML using an include-like approach: create a standalone XAML file that contains a resource dictionary, and then merge the dictionaries into your window's (or application's, or anything else really) resource dictionary:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="myresourcedictionary.xaml"/>
<ResourceDictionary Source="myresourcedictionary2.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
This can be a good approach for organizing a lot of styles and templates, though a problem with it is that if ResourceDictionary.MergedDictionaries
is set, you can't put any items directly in the dictionary, so you have to create a separate XAML file to contain the resources that belong solely to the window, which is kind of a pain.