So, I have already posted a question about the nested controls structure in WPF, it is here: Nested controls structure - in XAML or C#? And I have received a solution as follows:
<ItemsControl ItemsSource="{Binding SomeCollectionOfViewModel}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding SomeCollection}"> <!-- Nested Content -->
...
</DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>
I have used that solution, comming up with this:
<!-- The UniformGrids - boxes -->
<ItemsControl ItemsSource="{Binding UniformGridCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- The TextBoxes - Cells -->
<ItemsControl ItemsSource="{Binding TextBoxCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Here is the C# side:
public partial class MainWindow : Window
{
private readonly ObservableCollection<UniformGrid> uniformGridCollection = new ObservableCollection<UniformGrid>();
public ObservableCollection<UniformGrid> UniformGridCollection { get { return uniformGridCollection; } }
private readonly ObservableCollection<UniformGrid> textBoxCollection = new ObservableCollection<UniformGrid>();
public ObservableCollection<UniformGrid> TextBoxCollection { get { return textBoxCollection; } }
public MainWindow()
{
InitializeComponent();
for (int i = 1; i <= 9; i++)
{
UniformGrid box = new UniformGrid();
UniformGridCollection.Add(box);
UniformGrid cell = new UniformGrid();
TextBoxCollection.Add(cell);
}
DataContext = this;
}
}
But somehow the "Cells" - textboxes, that are inside the uniformgrids, do not create. Instead, I get only 9 uniform grids contain in one big uniform Grid (specified in Paneltemplate). I have checked the prgram with Snoop v 2.8.0: http://i40.tinypic.com/htzo5l.jpg
The question is: Could somebody tell me, why the inside structure(textboxes) arent created?
You're not defining any TextBox
es anywhere, That's why you're not getting any TextBox
es in the Visual Tree:
<Window x:Class="MiscSamples.NestedItemsControls"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="NestedItemsControls" Height="300" Width="300">
<ItemsControl ItemsSource="{Binding Level1}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ItemsControl ItemsSource="{Binding Level2}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBox Text="{Binding Value}"/> <!-- You Are missing this! -->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
Also, as mentioned in the comment, your Collections should be of ViewModel or Model types, not UI types:
ViewModels:
public class NestedItemsViewModel
{
public List<Level1Item> Level1 { get; set; }
}
public class Level1Item
{
public List<Level2Item> Level2 { get; set; }
}
public class Level2Item
{
public string Value { get; set; }
}
Code Behind:
public partial class NestedItemsControls : Window
{
public NestedItemsControls()
{
InitializeComponent();
DataContext = new NestedItemsViewModel()
{
Level1 = Enumerable.Range(0, 10)
.Select(l1 => new Level1Item()
{
Level2 = Enumerable.Range(0, 10)
.Select(l2 => new Level2Item { Value = l1.ToString() + "-" + l2.ToString() })
.ToList()
})
.ToList()
};
}
}
Notice that you will have to change the List
s to ObservableCollection
s if you expect these collections to change dynamically during runtime.
Also notice you have to implement INotifyPropertyChanged
properly.