4
votes

I have a combobox that I am populating via a CollectionViewSource. The items are build though a datatemplate for the incoming item type (in this case a ProjectViewModel). This is in WPF in .NET 4.0.

In my window.resources, I have specified the following:

    <Style TargetType="{x:Type ComboBoxItem}">
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
    </Style>

Despite this style, I am still getting the following errors:

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')

I have specified the Horizontal and Vertical ContentAlignment on the ComboBox element as well, to no avail. This is not a terrible problem as the items appear correctly. however when debugging, I do get about a 10 second delay when closing the window while it outputs about 4000 error messages to the output window (which I need open to catch legitimate binding errors.

I may not be reading the error correctly. Why can it not find a valid source for the binding? As far as I know, the way I am using the ComboBox and CollectionViewSource is in line with their intent.

4
I think someone fixed this here: stackoverflow.com/questions/2666439/…DJ Burb
@DJBurb The two suggestions in that question are essentially the same as the style that I have in my solution. I have tried the style at the app.xaml level, and I have tried naming it as the type name aslo. No changes. Something strange is afoot at the Circle K.CodeWarrior
I found that having the style in the app.xaml was the only way it would work. It didn't work on the element (the combo-box), the parent of the combo-box, the user-control, the window...andrew

4 Answers

5
votes

I'd thought I'd solved this problem in my own program, but found that it kept popping up intermittently. Finally managed to track down the source of the issue.

If you're using a combobox backed by an ICollectionView, and you stack two or more collectionView.Refresh() calls on the event queue (ie: calling refresh twice because of two different cleanup operations, for example), that will cause it to generate the binding error spam on each element of the combobox for each additional Refresh() call made. This binding error will only occur after you have opened the combobox at least once.

Rewriting it so that you only call Refresh() once for a given event will prevent the binding error from popping up.

3
votes

I just want to mention I struggled with this problem for two days. The most common suggested solution (adding the Horizontal/VerticalContentAlignment Style to your element, or even to the App.xaml) does NOT always solve the problem.

Eventually, I discovered something unique to my own situation - I hope it can be of help to someone: If you are using the FilterEventHandler, don't unsubscribe it before resubscribing!

My old code kept on generating that "Data Error 4" message whenever I changed the Channel Filter (which calls UpdateCorporatesList):

// This code generates errors
private void UpdateCorporatesList()
{
    this.CorporatesViewSource.Filter -= new FilterEventHandler(ApplyCorporateFilter);

    if (this.ChannelFilter != null)
    {
        this.CorporatesViewSource.Filter += new FilterEventHandler(ApplyCorporateFilter);
    }
    else
    {
        this.CorporateFilter = null;
    }
}

private void ApplyCorporateFilter(object sender, FilterEventArgs e)
{
    SalesCorporate customer = e.Item as SalesCorporate;
    var currentChannel = this.Channels.FirstOrDefault(x => x.ID == this.ChannelFilter).Description;
    if ((customer.ID != null) && (customer.Channel != currentChannel))
    {
        e.Accepted = false;
    }
}

...so I changed it to re-subscribe to the FilterEventHandler every time, and rather put the check for a null on Channel Filter in the event-handling method.

// This code works as intended
private void UpdateCorporatesList()
{
    this.CorporatesViewSource.Filter += new FilterEventHandler(ApplyCorporateFilter);

    if (this.ChannelFilter == null)
    {
        this.CorporateFilter = null;
    }
}

private void ApplyCorporateFilter(object sender, FilterEventArgs e)
{
    var currentChannel = this.Channels.FirstOrDefault(x => x.ID == this.ChannelFilter);
    if (currentChannel.ID == null)
    {
        return;
    }

    SalesCorporate customer = e.Item as SalesCorporate;
    if ((customer.ID != null) && (customer.Channel != currentChannel.Description))
    {
        e.Accepted = false;
    }
}

Et Voila! No more errors :-)

0
votes

I don't know if you still need help on this, but I just figured out a way to make this error/warning disapear. In my combobox, I redefined the ItemTemplate property like this :

<ComboBox.ItemTemplate>
    <ItemContainerTemplate>
        <TextBlock Text="{Binding Path=YourBinding}"/>
    </ItemContainerTemplate>
</ComboBox.ItemTemplate>

YourBinding is the value you would use as the "DisplayMemberPath" for the ComboBox

0
votes

Struggled with this error for few hours, tried every solution from google, only this one worked, remove OverridesDefaultStyle property line from your combobox style:

// before
<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="true" />
    <Setter Property="OverridesDefaultStyle" Value="true" />

// after
<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="SnapsToDevicePixels" Value="true" />

Using style template for combobox inside datagrid cell https://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/combobox-styles-and-templates?view=netframeworkdesktop-4.8