ComboBoxItem继续抛出绑定错误,尽管已经应用了样式。

6

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

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

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

尽管我按照这种样式,但仍然收到以下错误提示:
System.Windows.Data Error: 4 : 找不到绑定的源,参考'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 : 找不到绑定的源,参考'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')
我在ComboBox元素上指定了水平和垂直ContentAlignment,但是没有效果。虽然项目显示正确,但调试时关闭窗口时会有大约10秒的延迟,同时输出大约4000个错误消息到输出窗口(我需要打开以捕获合法的绑定错误)。
我可能没有正确地阅读错误。为什么它找不到绑定的有效源?就我所知,我使用ComboBox和CollectionViewSource的方式符合它们的意图。

我认为有人在这里修复了这个问题:https://dev59.com/RnE85IYBdhLWcg3wqleE - DJ Burb
@DJBurb 这个问题中的两个建议与我在解决方案中采用的风格本质上是一样的。我已经尝试了在 app.xaml 级别上使用这种风格,也尝试过将其命名为类型名称。但是没有改变。好像发生了一些奇怪的事情。 - CodeWarrior
我发现把样式写在app.xaml文件中是唯一可行的方式。样式不能写在元素(下拉框)、下拉框的父级容器、用户控件或窗口中。 - andrew
4个回答

7

我曾经以为在自己的程序中解决了这个问题,但发现它会间歇性地弹出。最终设法跟踪到问题的源头。

如果您使用由ICollectionView支持的组合框,并且在事件队列上堆叠两个或更多的collectionView.Refresh()调用(例如因为两个不同的清理操作而调用刷新两次),那么每个额外的Refresh()调用都会导致它在组合框的每个元素上生成绑定错误垃圾邮件。只有在您至少打开组合框一次之后才会出现此绑定错误。

将其重写为对于给定事件仅调用Refresh()一次将防止绑定错误弹出。


我的代码中只有一个手动刷新调用,但是移除它却解决了所有这些错误信息。感谢这个解决方案! - Bexo
我曾经遇到过类似的问题,我的项目源所使用的集合经常被更新/更改,这是导致问题的原因。我无法确认,但如果Refresh()在某个地方被调用,我也不会感到惊讶。 - A.R.

3

我想提一下,我为这个问题苦恼了两天。最常见的建议解决方案(向您的元素添加Horizontal/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;
    }
}

因此,我将其更改为每次重新订阅FilterEventHandler,并在事件处理方法中对Channel Filter进行空值检查。

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

好了,问题解决啦!:-)


2

我曾经为这个错误苦苦挣扎了几个小时,尝试了来自谷歌的每一个解决方案,只有这一个有效。从您的组合框样式中删除OverridesDefaultStyle属性行:

// 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" />

在数据网格单元格内使用样式模板的组合框

https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/combobox-styles-and-templates?view=netframeworkdesktop-4.8

仍然无法工作。 - Wang

0

我不知道你是否仍需要关于这个的帮助,但我刚刚想出了一种方法来消除这个错误/警告。 在我的组合框中,我重新定义了ItemTemplate属性,就像这样:

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

YourBinding是你在ComboBox中使用作为“DisplayMemberPath”的值。


我早就完成了那个项目,现在也没有轻松地访问源代码。我认为我有一个自定义的ItemTemplate,但我不确定。不幸的是,可能要过几个月(如果有可能)我才能回到那个项目并进行检查。 - CodeWarrior

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接