I am new to WPF, and I can't find a solution to my problem.
I've got an Observable Collection in my ViewModel:
ObservableCollection<Process>
Within the Process class is another ObervableCollection:
ObservableCollection<BurstTime>
I want to add a new User control (what can vizualize the actual state of Process data, and it's burst times) dynamically to one of my StackPanel in my view each time, when a new Process is activated, and remove it when the process is ended (when the observable collection changes).. During it's run, I want to diplay it's Burst Time collection, what can change in time..
I've tried to subscribe to the CollectionChanged event in my user control's codebehind and use a User Control inside another User Control and dynamicalli create required TextBlocks when my event handler runs, but I always get a System.Reflection.TargetInvocationException (inner exception: System.NullReferenceException) when my outer InitializeComponent() is running..
public ResourceUseView()
{
InitializeComponent();
((ObservableCollection<Process>)DataContext).CollectionChanged += ResourceUseView_CollectionChanged;
}
Is it possible to do it? Is it possible to create or remove User controls in my outer UserControl's codebehind while reacting to ObservableCollection's element changes, and update the outer when an element changes in the inner ObservableCollection? Are there other ways than instantiate a UserControl inside another User Control dynamically? Is there any special control, what can display ObservableCollection in ObservableCollection?
(If it'is possible, I would like to have different user controls as much as elements my ObservableCollection have..)
Thanks for your help!
The constructor runs before the data binding, so you are probably seeing that error because the DataContext
is null
at the time the constructor runes.
To bind to a collection, use a control that contains an ItemsSource
property. And if you want to bind to a nested collection, modify the ItemTemplate
of the control to use another control with an ItemsSource
property for the nested collection.
Here's an example using an ItemsControl
<ItemsControl ItemsSource="{Binding Processes}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding BurstTimes}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I have some examples of the ItemsControl
on my blog if you're interested.
If you want to specify a UserControl
for each object, then set the ItemTemplate
for the first ItemsControl
to be the ProcessUserControl
, and inside the ProcessUserControl
have an ItemsControl
bound to BurstTimes
and use a BurstTimeUserControl
for it's ItemTemplate
<ItemsControl ItemsSource="{Binding Processes}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:ProcessUserControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
...
<UserControl x:Class="MyNamespace.ProcessUserControl ...>
...
<ItemsControl ItemsSource="{Binding BurstTimes}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:BurstTimeUserControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
...
</UserControl>