I have a ConfigList
object with a name and a Dictionary
and I need to nest ItemsControls
with different ItemsSource
.
I tried to do it this way :
<ItemsControl x:Name="TestStep" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=ConfigList }" HorizontalAlignment="Center" VerticalAlignment="Center">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Ictrl.Nom}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl
ItemsSource="{Binding Path=Param}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Key}" />
<TextBlock Text=" : " />
<TextBlock Text="{Binding Path=Value}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ItemsControl>
When I start my application, I've got this error :
System.Windows.Markup.XamlParseException : '' Adding a value to the collection of type 'System.Windows.Controls.ItemCollection' threw an exception. ' line number '25' and line position '14'. '
Internal Exception InvalidOperationException: Invalid operation when ItemsSource is in use. Access and edit items with ItemsControl.ItemsSource.
Any idea what the problem is?
You set an ItemsSource
on the ItemsControl
. The data template is used to create the controls that display the data. The created items are then put into the Items
collection of the ItemsControl
. If you add an element to the ItemsControl
directly in XAML this will put them into the Items
collection, too. Doing both is not allowed. You either specify an ItemsSource
or add to Items
directly. From the documentation:
Note that you use either the Items or the
ItemsSource
property to specify the collection that should be used to generate the content of yourItemsControl
. When theItemsSource
property is set, theItems
collection is made read-only and fixed-size.
However, in your case this is not the real issue, because your markup is wrong for what you want to achieve. If you you really intended to nest ItemsControl
s, you would simply change the data template for the outer ItemsControl
to contain another ItemsControl
that binds to a collection property within the outer data item. Since there is already a TextBox
, you have to use a panel (e.g. StackPanel
) to host multiple controls in the template.
<ItemsControl x:Name="TestStep" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding Path=ConfigList }" HorizontalAlignment="Center" VerticalAlignment="Center">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=Ictrl.Nom}" />
<ItemsControl ItemsSource="{Binding Path=Param}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Key}" />
<TextBlock Text=" : " />
<TextBlock Text="{Binding Path=Value}" />
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
If you want to have a hierarchical view of your data, using a TreeView
might be a better fit.