1
votes

I have a custom listbox class, and when use it, everytime (time-to-time) getting the following runtime binding exceptions and more (even though the listbox works fine):

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ListBox', AncestorLevel='1''. BindingExpression:Path=IsGroupped; DataItem=null; target element is 'GroupItem' (Name=''); target property is 'NoTarget' (type 'Object')

And this:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ListBox', AncestorLevel='1''. BindingExpression:Path=IsGroupped; DataItem=null; target element is 'ContentPresenter' (Name=''); target property is 'NoTarget' (type 'Object').

Please tell me somebody why this comes?

The listbox xaml looks like this:

<ListBox x:Class="MyApp.SubControls.ProduktListBox"
                 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:System="clr-namespace:System;assembly=mscorlib"
                 xmlns:konfig="clr-namespace:MyApp.Konfig"
                 xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
                 xmlns:subControls="clr-namespace:MyApp.SubControls"
                 xmlns:dal="clr-namespace:MyApp.DAL"
                 mc:Ignorable="d"
                 d:DesignHeight="300"
                 d:DesignWidth="300"
                 VirtualizingStackPanel.IsVirtualizing="True"
                 VirtualizingStackPanel.VirtualizationMode="Recycling"
                 ScrollViewer.IsDeferredScrollingEnabled="True"
                 ItemsSource="{konfig:CultureBinding}"
                 IsSynchronizedWithCurrentItem="True"
         >

    <ListBox.Resources>

        <ItemsPanelTemplate x:Key="ItemPanelTemplateGroupped">
            <UniformGrid Columns="3"
                         IsItemsHost="True"
                         HorizontalAlignment="Stretch" />
        </ItemsPanelTemplate>
        <ItemsPanelTemplate x:Key="ItemPanelTemplateNormal">
            <StackPanel Orientation="Vertical" />
        </ItemsPanelTemplate>

        <ControlTemplate TargetType="{x:Type GroupItem}"
                         x:Key="defaultGroup">
            <ItemsPresenter />
        </ControlTemplate>

        <ControlTemplate TargetType="{x:Type GroupItem}"
                         x:Key="grouppedTemplate">

            <Expander IsExpanded="True">
                <Expander.Header>

                    <TextBlock Text="{Binding Path=Name}"
                               FontWeight="Bold"
                               HorizontalAlignment="Center" />

                </Expander.Header>
                <ItemsPresenter />
            </Expander>

        </ControlTemplate>


        <ControlTemplate TargetType="{x:Type ListBoxItem}" x:Key="NormalControlTemplate">
            <Border Name="ItemBorder"
                    BorderThickness="2"
                    BorderBrush="Black"
                    Margin="0">
                <ContentPresenter />
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsSelected"
                         Value="true">
                    <Setter TargetName="ItemBorder"
                            Property="BorderThickness"
                            Value="2" />
                    <Setter TargetName="ItemBorder"
                            Property="Background"
                            Value="{StaticResource BorderBrushBackgroundMouseOver}" />
                    <Setter TargetName="ItemBorder"
                            Property="BorderBrush"
                            Value="{StaticResource BorderBrushMouseOver}" />
                </Trigger>
                <Trigger Property="IsSelected"
                         Value="False">
                    <Setter TargetName="ItemBorder"
                            Property="BorderThickness"
                            Value="0" />
                    <Setter TargetName="ItemBorder"
                            Property="Background"
                            Value="{x:Null}" />
                    <Setter TargetName="ItemBorder"
                            Property="BorderBrush"
                            Value="{StaticResource ActionBrush}" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>

        <ControlTemplate TargetType="{x:Type ListBoxItem}" x:Key="GrouppedControlTemplate">
            <Border BorderThickness="1"
                    x:Name="ItemBorder"
                    BorderBrush="Black"
                    Margin="1">
                <ContentPresenter />
            </Border>
            <ControlTemplate.Triggers>
                <Trigger Property="IsSelected"
                         Value="true">
                    <Setter TargetName="ItemBorder"
                            Property="BorderThickness"
                            Value="2" />
                    <Setter TargetName="ItemBorder"
                            Property="Background"
                            Value="#AAAAAA" />
                </Trigger>

            </ControlTemplate.Triggers>
        </ControlTemplate>

        <DataTemplate x:Key="ItemTemplateNormal" DataType="{x:Type dal:Produkt}">
            <Border x:Name="BorderControl"
                    Margin="1"
                    Cursor="Hand"
                    BorderThickness="0"
                    Padding="2"
                    ToolTipService.ShowDuration="100000">

                ...
            </Border>

        </DataTemplate>

        <DataTemplate x:Key="ItemTemplateGroupped"  DataType="{x:Type dal:Produkt}">
           ...

        </DataTemplate>

        <DataTemplate x:Key="TemplateSelector">
            <ContentPresenter Content="{Binding}" Name="contentPresenter" />

            <DataTemplate.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=IsGroupped}" Value="False">
                    <Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource ItemTemplateNormal}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=IsGroupped}" Value="True">
                    <Setter TargetName="contentPresenter" Property="ContentTemplate" Value="{StaticResource ItemTemplateGroupped}" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>

    </ListBox.Resources>

    <ListBox.Style>
        <Style TargetType="ListBox">
            <Setter Property="ItemsPanel" Value="{StaticResource ItemPanelTemplateNormal}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsGroupped}" Value="True">
                    <Setter Property="ItemsPanel"
                            Value="{StaticResource ItemPanelTemplateGroupped}" />
                </DataTrigger>

            </Style.Triggers>
        </Style>
    </ListBox.Style>

    <ListBox.GroupStyle>
        <GroupStyle>
            <GroupStyle.ContainerStyle>
                <Style TargetType="{x:Type GroupItem}">
                    <Setter Property="Template"  Value="{StaticResource defaultGroup}"/>

                    <Style.Triggers>
                        <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type ListBox}}, Path=IsGroupped}" Value="True">
                            <Setter Property="Template" Value="{StaticResource grouppedTemplate}" />
                        </DataTrigger>
                    </Style.Triggers>

                </Style>
            </GroupStyle.ContainerStyle>
        </GroupStyle>
    </ListBox.GroupStyle>

    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template" Value="{StaticResource NormalControlTemplate}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBox}}, Path=IsGroupped}" Value="True">
                    <Setter Property="Template" Value="{StaticResource GrouppedControlTemplate}" />
                </DataTrigger>


            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>

</ListBox>

The code behind:

 public partial class ProduktListBox:ListBox
    {
        public bool IsGroupped
        {
            get { return (bool)GetValue(IsGrouppedProperty); }
            set { SetValue(IsGrouppedProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsGroupped.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsGrouppedProperty =
            DependencyProperty.Register("IsGroupped", typeof(bool), typeof(ProduktListBox), new PropertyMetadata(false));

        public ProduktListBox()
        {
            InitializeComponent();
            this.Loaded += ListBox_Loaded;

        }

        private void ListBox_Loaded(object sender, RoutedEventArgs e)
        {
            ItemTemplate = FindResource("TemplateSelector") as DataTemplate;
        }
}
1
Why are you setting the itemtemplate in code? This is once the listbox is loaded and could cause problems but looks like it may as well just be set in markup anyhow.Andy

1 Answers

-1
votes

Try this:

<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBox}}, Path=IsGroupped}" Value="True">