尽管有样式,ComboBoxItem仍会引发绑定错误

Cod*_*ior 4 data-binding wpf combobox datatemplate

美好的一天,

我有一个通过CollectionViewSource填充的组合框。通过传入项目类型的数据模板(在本例中为ProjectViewModel)构建项目。这是.NET 4.0中的WPF。

在我的window.resources中,我指定了以下内容:

    <Style TargetType="{x:Type ComboBoxItem}">
        <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
    </Style>
Run Code Online (Sandbox Code Playgroud)

尽管有这种风格,我仍然遇到以下错误:

System.Windows.Data错误:4:找不到参考'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ItemsControl',AncestorLevel ='1''的绑定源。BindingExpression:Path = Horizo​​ntalContentAlignment; DataItem = null; 目标元素是'ComboBoxItem'(Name =''); 目标属性为“ Horizo​​ntalContentAlignment”(类型为“ Horizo​​ntalAlignment”)

System.Windows.Data错误:4:找不到参考'RelativeSource FindAncestor,AncestorType ='System.Windows.Controls.ItemsControl',AncestorLevel ='1''的绑定源。BindingExpression:Path = VerticalContentAlignment; DataItem = null; 目标元素是'ComboBoxItem'(Name =''); 目标属性为“ VerticalContentAlignment”(类型为“ VerticalAlignment”)

我也对ComboBox元素指定了水平和垂直ContentAlignment,但无济于事。这不是一个严重的问题,因为项目正确显示。但是,在调试时,关闭窗口时确实会延迟约10秒钟,同时它将大约4000条错误消息输出到输出窗口(我需要打开它才能捕获合法的绑定错误。

我可能无法正确读取错误。为什么找不到绑定的有效来源?据我所知,我使用ComboBox和CollectionViewSource的方式符合他们的意图。

dsm*_*ith 5

我以为我已经在自己的程序中解决了这个问题,但是发现它不断间歇地弹出。最终设法找到问题的根源。

如果您使用的是带有的组合框ICollectionView,并且collectionView.Refresh()在事件队列上堆叠了两个或多个调用(例如,由于两次不同的清除操作而调用两次刷新),这将导致它在上生成垃圾邮件绑定错误每个附加Refresh()调用的组合框的每个元素。仅在您至少打开一次组合框之后,才会发生此绑定错误。

重写它,以便只Refresh()给定事件调用一次,这样可以防止出现绑定错误。


Hel*_*iac 3

我只想提一下我在这个问题上挣扎了两天。最常见的建议解决方案(将 Horizo​​ntal/VerticalContentAlignment 样式添加到元素,甚至 App.xaml)并不总能解决问题。

最终,我发现了一些与我自己的情况不同的东西 - 我希望它可以对某人有所帮助:如果您正在使用 FilterEventHandler,请不要在重新订阅之前取消订阅!

每当我更改通道过滤器(调用 UpdateCorporatesList)时,我的旧代码都会继续生成“数据错误 4”消息:

// 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

...所以我将其更改为每次都重新订阅 FilterEventHandler,而是将在事件处理方法中对 Channel Filter 进行 null 检查。

// 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

瞧瞧!不再有错误:-)