Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot find source for binding with reference 'RelativeSource FindAncestor

I am using a compositecollection:

  • Comboboxitem with content "Select a vendor"
  • Collectioncontainer bound to a Observablecollection of Vendor objects

The desired functionality: the user has to select a vendor from the combobox. Selecting "Select a vendor" sets the Vendor property in the viewmodel to null.

I am getting an binding error. Any ideas how to fix this?

Error when debugging

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'ComboBoxItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment')
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', AncestorLevel='1''. BindingExpression:Path=VerticalContentAlignment; DataItem=null; target element is 'ComboBoxItem' (Name=''); target property is 'VerticalContentAlignment' (type 'VerticalAlignment')

XAML

<ComboBox Name='cmbVendor'
            SelectedItem='{Binding Vendor, Converter={StaticResource ComboboxConverter}, Mode=TwoWay}'
            IsSynchronizedWithCurrentItem='True'>
    <ComboBox.Resources>
      <CollectionViewSource x:Key='VendorsCollection'
                            Source='{Binding Vendors}' />
      <DataTemplate DataType='{x:Type ComboBoxItem}'>
        <TextBlock Text='{Binding Content}' />
      </DataTemplate>
      <DataTemplate DataType='{x:Type objects:Vendor}'>
        <StackPanel>
          <TextBlock Text='{Binding Name}' />
        </StackPanel>
      </DataTemplate>
    </ComboBox.Resources>
    <ComboBox.ItemsSource>
      <CompositeCollection>
        <ComboBoxItem Content='Select a vendor' />
        <CollectionContainer Collection='{Binding Source={StaticResource VendorsCollection}}' />
      </CompositeCollection>
    </ComboBox.ItemsSource>
  </ComboBox>

ComboboxConverter

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {

      var vendor = value as Vendor;
        if (vendor != null)
        {
            return vendor;
        }

        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var vendor = value as Vendor;
        if (vendor != null)
        {
            return vendor;
        }

        var comboboxItem = value as ComboBoxItem;
        if (comboboxItem != null)
        {
            return null;
        }
        return null;
    }
like image 718
BertAR Avatar asked Apr 18 '26 19:04

BertAR


2 Answers

Add to your App.xaml

<Style TargetType="{x:Type ComboBoxItem}">
    <Setter Property="HorizontalContentAlignment" Value="Left" />
    <Setter Property="VerticalContentAlignment" Value="Top" />
</Style>
like image 107
NielW Avatar answered Apr 20 '26 12:04

NielW


The ComboBox (and other WPF controls) by default use a VirtualizingPanel for the ItemsPanel. If you change your items panel to not be a VirtualizingPanel or if you set the VirtualizingPanel.IsVirtualizing attached property to false, you will not see this runtime error.

<ComboBox Name="cmbVendor"
          SelectedItem="{Binding Vendor, Converter={StaticResource ComboboxConverter}, Mode=TwoWay}"
          IsSynchronizedWithCurrentItem="True"
          VirtualizingPanel.IsVirtualizing="False">
</ComboBox>

or

<ComboBox Name="cmbVendor"
          SelectedItem="{Binding Vendor, Converter={StaticResource ComboboxConverter}, Mode=TwoWay}"
          IsSynchronizedWithCurrentItem="True">
    <ComboBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel IsItemsHost="True" />
        </ItemsPanelTemplate>
    </ComboBox.ItemsPanel>
</ComboBox>

This is what worked for me instead of just ignoring the runtime error. I also tried changing the VirtualizationMode property of the VirtualizingStackPanel to both Standard and Recycling but that did not have any effect and the runtimes errors still occurred.

Finally, if you really do need virtualization because your ComboBox may contain many items (e.g. 100s) then I suggest overriding the Style or Template of the ComboBoxItem and setting the HorizontalContentAlignment and VerticalContentAlignment properties explicitly.

You can do this in the XAML Designer in Visual Studio by selecting your ComboBox in the Document Outline window and then right-clicking the ComboBox node and selecting Edit Additional Templates...Edit Generated Item Container (ItemContainerStyle). Then change the generated style for those two properties from:

<Style TargetType="{x:Type ComboBoxItem}">
    ...
    <Setter Property="HorizontalContentAlignment"
            Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
    <Setter Property="VerticalContentAlignment"
            Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
    ...
</Style>

to this or whatever you'd like:

<Style TargetType="{x:Type ComboBoxItem}">
    ...
    <Setter Property="HorizontalContentAlignment"
            Value="Stretch" />
    <Setter Property="VerticalContentAlignment"
            Value="Stretch" />
    ...
</Style>
like image 25
tia.misu Avatar answered Apr 20 '26 12:04

tia.misu



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!