Reputation: 63
I was wondering if its possible to somehow bind a list of lists to a cavas panel. For example having object "layer" which itself is a list of "rectangle" objects. Would if be possible to bind a list of layers to a canvas? So far I can only do it by binding a flattened INumerable of the nested list (using SelectMany function) to an itemcontrol, but this isnt good enough, Id like to keep the "layers" separate and have the Zindex of the rectangles vary according to the layer it is at, allowing to reorder the layers easily.
I have also tried having nested itemcontrols but as expected it only displays the first layer. The aim is to draw a rectangle for every object in every layer on the canvas allowing for layer manipulation, insertion of new objects in each layer, etc...
Thanks in advance! :)
Upvotes: 2
Views: 2005
Reputation: 11051
Like H.B said, i too can't see a reason why it will not work. Having an ItemsControl
in another ItemsContainer works perfectly fine.
<ItemsControl ItemsSource="{Binding Layers}">
<ItemsControl.ItemsContainerStyle>
<Style>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<ItemsControl ItemsSource="{Binding Rectangles}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ItemsControl.ItemsContainerStyle>
</ItemsControl>
But it think it would be cleaner to put the sub ItemsControl
inside an DataTemplate
for your Items, without the need to modify the ItemsContainerStyle
. I think its bad design if your control needs to know informations about the properties of the model, which is necessary for binding to Rectangles
.
Upvotes: 0
Reputation: 185445
How about making the ItemTemplate
of the main ItemsControl another ItemsControl with yet another Canvas as ItemsPanel
? (I do not see a reason why it should only display the first layer)
Actually the main ItemsControl does not need to be a Canvas, a Grid would do as well (at least unless your collections have coordinates of their own or a Z-Order, if you use a grid the layer order is he same as their appearance in the collection).
An example (a bit verbose but can't do anything about that):
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding LayerItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style TargetType="{x:Type ContentPresenter}">
<!-- Here would the binding to some properties that take care of placement -->
<Setter Property="Canvas.Top" Value="{Binding Top}" />
<Setter Property="Canvas.Left" Value="{Binding Left}" />
</Style>
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<!-- Some template for the individual items -->
<DataTemplate>
<Border Padding="5" BorderThickness="1" BorderBrush="Red" CornerRadius="3"
Background="White">
<TextBlock Text="{Binding Name}" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Upvotes: 3