问题
Good day,
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.
回答1:
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.
回答2:
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 :-)
回答3:
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
来源:https://stackoverflow.com/questions/15070861/comboboxitem-continues-to-throw-binding-error-despite-style