I have a main window with a single user control in it, called SuperMode
. SuperMode
consists of a collection of people and each person in this collection has their own collection of tasks. Sounds simple, right?
From file SuperMode.xaml
:
<UserControl
x:Class="Prototype.SuperMode"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Prototype"
DataContext="{Binding RelativeSource={RelativeSource Self}}"> <!-- NOTE! -->
<!-- Look at how I'm setting the DataContext, as I think it's
important to solve the problem! -->
<ScrollViewer CanContentScroll="True">
<ItemsControl ItemsSource="{Binding People}" Margin="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="1"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</ScrollViewer>
</UserControl>
This works fine and I can see four people as I expect! Now all I have to do is get the XAML right for the Person
user control so that all of their tasks are displayed as well.
As you can see, I'm using the People
property to populate the control with items. The People
property has type ObservableCollection<Person>
, where Person
is another user control as such...
From Person.xaml
:
<UserControl
x:Class="Prototype.Person"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Prototype">
<Border Background="Black" CornerRadius="4" Margin="1">
<ItemsControl ItemsSource="{Binding Tasks}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Border>
</UserControl>
Tasks
here is a property of Person
with type ObservableCollection<Task>
. This is where it gets stuck! Apparently WPF cannot find any Tasks
property and looking at the output window from VS2008, I find the following:
System.Windows.Data Error: 39 : BindingExpression path error: 'Tasks' property not found on 'object' ''SuperMode' (Name='SuperMode')'. BindingExpression:Path=Tasks; DataItem='SuperMode' (Name='SuperMode'); target element is 'ItemsControl' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')
Now I'm lost. It seems that I have to set the DataContext
attribute on each Person
, otherwise it will still think that the data context is SuperMode
, but how do I do that?