I suspect the answer to my problem is pretty simple but I have had a good look around the forum and can't seem to find anything quite the same.
I have a reasonably complex binding structure with a ItemsControl at the far end but it only shows the first item. I can see the data on the code side is correct and holds only 8 items, the first item is displayed correctly with all labeling and colours as required.
The logic side structure is like:
- MainWindow Partial Class
- ObservableCollection of WaterSamplerClass
- ParametersClass (single instance of a class)
- ObservableCollection of bottleStateClass
- int Number (Property)
- string Label (Property)
- ObservableCollection of bottleStateClass
- ParametersClass (single instance of a class)
- ObservableCollection of WaterSamplerClass
The XAML structure is like:
- MainWindow Partial Class
- ControlTemplate GroupBox (DataContext WaterSampler instance from the list set in code)
- DataTemplate containing button that uses bottleState control template
- ItemsControl using DataTemplate to show lots of bottleStates
- ControlTemplate containing the decoration of the Button used in the ItemsControl
- ControlTemplate GroupBox (DataContext WaterSampler instance from the list set in code)
Here's a simplified version of the code:
Items control and its data template inside the GroupBox ControlTemplate whose datacontext is an instance of WaterSampler.
<ControlTemplate x:Key="WaterSamplerGroupBoxTemplate" TargetType="{x:Type GroupBox}" >
<GroupBox Header="{Binding Path=Header}" Width="300" Margin="10,5,10,0" HorizontalAlignment="Center">
<StackPanel Orientation="Horizontal">
<StackPanel.Resources>
<DataTemplate x:Key="BottleStateDataTemplate">
<Button Template="{DynamicResource ValveStatusTemplate}" />
</DataTemplate>
</StackPanel.Resources>
<ItemsControl Name="bottleStateListBox" ItemTemplate="{StaticResource BottleStateDataTemplate}" Margin="5" Height="50" ItemsSource="{Binding BottleIsFullList}" DataContext="{Binding Parameters}"/>
</StackPanel>
</GroupBox>
</ControlTemplate>
The simplified button control template:
<ControlTemplate x:Key="ValveStatusTemplate" TargetType="{x:Type Button}" >
<StackPanel Orientation="Vertical" Width="30" Margin="5" >
<TextBlock Text="{Binding Number}" FontSize="18" Canvas.Left="8"/>
</StackPanel>
</ControlTemplate>
The class that holds the data for the item template:
public class DisplayBottleStateClass : INotifyPropertyChanged
{
private int number;
public int Number
{
get { return number; }
}
}
The class containing the list of DisplayBottleClass:
public class WSParametersClass : INotifyPropertyChanged
{
private List<DisplayBottleStateClass> bottleIsFullList = new List<DisplayBottleStateClass>();
public List<DisplayBottleStateClass> BottleIsFullList
{
get { return bottleIsFullList; }
}
}
The class containing the parameters class:
public class WaterSampler : INotifyPropertyChanged
{
private WSParametersClass parameters = new WSParametersClass();
public WSParametersClass Parameters
{
get { return parameters; }
set { parameters = value; OnPropertyChanged("Parameters"); }
}
}
Finally the MainWindow class:
public partial class MainWindow : Window
{
public class WaterSamplerListClass : ObservableCollection<WaterSampler> { }
private WaterSamplerListClass waterSamplers = new WaterSamplerListClass();
public MainWindow()
{
waterSamplers.Add(new WaterSampler(0));
WaterSampler0Group.DataContext = (waterSamplers[0]);
}
}
I do get a binding error for the two brushes that I use but when I replace these with fixed values in the XAML still only the first element is displayed. The list also seems to update correctly through the binding as I can see the first element changing correctly. The error I get is:
System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=GradientStopHighlight; DataItem=null; target element is 'GradientStop' (HashCode=23577486); target property is 'Color' (type 'Color')
Any suggestions would be very welcome.
Thanks very much
Ed