1
votes

The following sample seems to work fine, yet produces a whole bunch of binding errors in the output window, how can I resolve them as I use the output window heavily and don't want it cluttered with these errors.

public partial class Window1 : Window
{
    public class Item
    {
        public Color Colour { get; set; }
        public double Thickness { get; set; }
    }

    public ObservableCollection<Item> Items { get; private set; }

    public Window1()
    {
        Items = new ObservableCollection<Item>();
        Items.Add(new Item() { Colour = Colors.Red, Thickness = 1 });
        Items.Add(new Item() { Colour = Colors.Green, Thickness = 2 });
        Items.Add(new Item() { Colour = Colors.Blue, Thickness = 3 });

        DataContext = this;
        InitializeComponent();
    }

    protected override void OnPreviewMouseDoubleClick(MouseButtonEventArgs e)
    {
        base.OnPreviewMouseDoubleClick(e);

        if(Items.Count > 0)
            Items.RemoveAt(Items.Count-1);
    }
}
<Window x:Class="WpfApplication67.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ContentControl>
    <ContentControl.Template>
        <ControlTemplate>
            <Border Name="b">
                <ItemsControl ItemsSource="{Binding Items}" DisplayMemberPath="Colour"/>
            </Border>
           
            <ControlTemplate.Triggers>
                <DataTrigger Binding="{Binding Items.Count}" Value="0">
                    <Setter TargetName="b" Property="BorderBrush" Value="Red"/>
                    <Setter TargetName="b" Property="BorderThickness" Value="8"/>
                </DataTrigger>

                <DataTrigger Binding="{Binding Items.Count}" Value="1">
                    <Setter TargetName="b" Property="BorderBrush">
                        <Setter.Value>
                            <SolidColorBrush Color="{Binding Items[0].Colour}"/>
                        </Setter.Value>
                    </Setter>
                    <Setter TargetName="b" Property="BorderThickness" Value="{Binding Items[0].Thickness}"/>
                </DataTrigger>
                
                <DataTrigger Binding="{Binding Items.Count}" Value="2">
                    <Setter TargetName="b" Property="BorderBrush">
                        <Setter.Value>
                            <SolidColorBrush Color="{Binding Items[1].Colour}"/>
                        </Setter.Value>
                    </Setter>
                    <Setter TargetName="b" Property="BorderThickness" Value="{Binding Items[1].Thickness}"/>
                </DataTrigger>
                
                <DataTrigger Binding="{Binding Items.Count}" Value="3">
                    <Setter TargetName="b" Property="BorderBrush">
                        <Setter.Value>
                            <SolidColorBrush Color="{Binding Items[2].Colour}"/>
                        </Setter.Value>
                    </Setter>
                    <Setter TargetName="b" Property="BorderThickness" Value="{Binding Items[2].Thickness}"/>
                </DataTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </ContentControl.Template>
</ContentControl>

When I start the application I get the following errors

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Items[2].Colour; DataItem='Window1' (Name=''); target element is 'SolidColorBrush' (HashCode=47633461); target property is 'Color' (type 'Color')

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Items[0].Colour; DataItem=null; target element is 'SolidColorBrush' (HashCode=45523402); target property is 'Color' (type 'Color')

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Items[1].Colour; DataItem=null; target element is 'SolidColorBrush' (HashCode=35287174); target property is 'Color' (type 'Color')

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=Items[2].Colour; DataItem=null; target element is 'SolidColorBrush' (HashCode=44419000); target property is 'Color' (type 'Color')

And then when I click to remove an item, I get

System.Windows.Data Error: 16 : Cannot get 'Item[]' value (type 'Item') from 'Items' (type 'ObservableCollection`1'). BindingExpression:Path=Items[2].Thickness; DataItem='Window1' (Name=''); target element is 'Border' (Name='b'); target property is 'BorderThickness' (type 'Thickness') TargetInvocationException:'System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.

1
See this answer, may be help. – Anatoliy Nikolaev

1 Answers

0
votes

Looks like you can't avoid this "error" as it is caused by WPF optimization. What you can do is reduce the number of errors (and get rid of copypasta) using one of the following methods:

  1. Add LastItem property to Window1. Update it when Items collection is changed. Notify about changes by implementing INotifyPropertyChanged interface.

  2. Create LastListItemConverter which implements IValueConverter and returns the last item of a list.

Both methods will make duplicate DataTriggers unnecessary.