(After pulling hair for 8 consecutive hours, I've given up. Will be very thankful if someone could come to rescue):
Here's what I have:
AlbumItem: This is an ItemsControl
that uses a Canvas
as its ItemsPanel
and binds to a colletion property of the underlying VM. A handful of DataTemplate
s defined in Resources
section of this control perform conversion of ViewModel objects into UI objects. This control works really nicely and as expected.
Album: This again is an ItemsControl
that uses a UniformGrid
as its ItemsPanel
and binds to a colletion property of the underlying VM. This control shows a grid of AlbumItem
s. I have set the ItemTemplate
of this control to AlbumItem
.
No matter what I do, this second control doesn't use its ItemTemplate
to display its items. UniformGrid
works nicely and I get a 3 x 3 grid of items, but each of those items is a simple TextBlock
showing the class name of the underlying VM object.
I have tried to use a DataTemplate
too, instead of using ItemTemplate
, to no avail.
Can anyone see where is it going wrong?
Posting a working sample would be a huge undertaking (this is a complex project), but I can post relevant XAML here:
AlbumItem
<ItemsControl x:Class="AlbumItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:bd="clr-namespace:ViewProject"
xmlns:vm="clr-namespace:ViewModelProject"
mc:Ignorable="d"
ItemsSource="{Binding Path=Children}"
ClipToBounds="True" Background="LightYellow">
<ItemsControl.Resources>
<BooleanToVisibilityConverter x:Key="B2VConverter" />
<DataTemplate DataType="{x:Type vm:Ellipse}">
<Ellipse IsHitTestVisible="False" StrokeThickness="{Binding BorderThickness}" Fill="{Binding Fill, Mode=OneWay}" Stroke="{Binding Stroke, Mode=OneWay}" />
</DataTemplate>
</ItemsControl.Resources>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas HorizontalAlignment="Left" VerticalAlignment="Top" Focusable="true" Width="{Binding Size.Width}" Height="{Binding Size.Height}" FocusVisualStyle="{x:Null}">
</Canvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemContainerStyle>
<Style>
<Setter Property="Canvas.Left" Value="{Binding Path=Location.X}" />
<Setter Property="Canvas.Top" Value="{Binding Path=Location.Y}" />
<Setter Property="Panel.ZIndex" Value="{Binding Path=GlobalZOrder}" />
</Style>
</ItemsControl.ItemContainerStyle>
</ItemsControl>
Album
<ItemsControl x:Class="Album"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:bd="clr-namespace:ViewProject"
xmlns:vm="clr-namespace:ViewModelProject"
d:DesignHeight="500" d:DesignWidth="800"
ItemsSource="{Binding Drawing.Baked}"
ClipToBounds="True">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="3" Columns="3" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate DataType="vm:ReadonlyDrawingVM">
<bd:AlbumItem />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I have used Snoop to confirm the following:
DataContext
is correct. So is its ItemsSource
. I can actually see all the VM objects in Snoop when I delve ItemsSource
.ItemTemplate
and/or ItemsPanel
properties of Album, I see all the items (i.e. a TextBlock with their class name) in the form of a grid or list depending upon the property that I reset.This turned out to be due to the underlying data source. I was binding Album with a List<T>
, which didn't update the UI with the changes in its items due to the following line of the underlying property Baked
:
If _Baked Is value Then Return
This is the first line in Baked
property setter (I'm using the default property template provided by MVVM Light). Since I never assigned a new List<T>
to _Baked
; only changed items within it, the above line would stop property change notification from being raised. Once I fixed this, my Album started getting populated.