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;
}
}