0
votes

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)

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

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

2
That is a lot of moving parts and an error on paths and elements you have not shown. You might have more luck in getting an answer if you simplify the problem. Remove code and xaml to the bare minimum.Lars Truijens
This is the closest question to the problem i am facing right now. I wander did you resolved it back then? I don;t have any binding errors, but still only the first element in the nested list is displayed in the view. Thanks.ljubomir

2 Answers

0
votes

Your ItemsControl declares both an ItemsSource and a DataContext. I believe these two properties are mutually exclusive - setting the DataContext property disconnects the control from the data associated with the logical control tree.

Remove the DataContext= data binding and I think you'll see the items in the ItemsSource appear in your ItemsControl.

Also, note that ItemsControl doesn't provide any UI definition on its own. For debugging purposes, it can be useful to drop in a ListBox or other concrete ItemsControl and give it the same data binding settings to verify that your data bindings are sane. If the ItemsControl doesn't show anything but the ListBox does, then your problem isn't in data binding, but in templating the ItemsControl visuals.

0
votes

Try set the CacheLength property on the ItemsPanelTemplate.ItemsStackPanel of your ItemsControl.

CacheLength as defined by MSDN:

The size of the buffers for items outside the viewport, in multiples of the viewport size. The default is 4.0.

Remarks

To improve scrolling performance, ItemsStackPanel creates and caches item containers for items that are off-screen on both sides of the viewport. The CacheLength property specifies the size of the buffers for the off-screen items. You specify CacheLength in multiples of the current viewport size. For example, if the CacheLength is 4.0, 2 viewports worth of items are buffered on each side of the viewport. You can set a smaller cache length to optimize startup time, or set a larger cache size to optimize scrolling performance. Item containers that are off-screen are created at a lower priority than those in the viewport.