【问题标题】:ComboBoxItem continues to throw binding error despite style尽管样式,ComboBoxItem 继续抛出绑定错误
【发布时间】:2013-02-10 19:49:59
【问题描述】:

我有一个通过 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 错误:4:找不到绑定源 参考'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', 祖先级别='1''。 BindingExpression:Path=Horizo​​ntalContentAlignment; 数据项=空;目标元素是'ComboBoxItem'(名称='');目标 属性是“Horizo​​ntalContentAlignment”(类型“Horizo​​ntalAlignment”)

System.Windows.Data 错误:4:找不到绑定源 参考'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.ItemsControl', 祖先级别='1''。绑定表达式:路径=垂直内容对齐; 数据项=空;目标元素是'ComboBoxItem'(名称='');目标 属性是“VerticalContentAlignment”(类型“VerticalAlignment”)

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

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

【问题讨论】:

  • 我想有人在这里解决了这个问题:stackoverflow.com/questions/2666439/…
  • @DJBurb 该问题中的两个建议与我在解决方案中的风格基本相同。我已经尝试过 app.xaml 级别的样式,并且尝试将其命名为类型名称。没有变化。 K 圈发生了一些奇怪的事情。
  • 我发现 app.xaml 中的样式是唯一可行的方法。它不适用于元素(组合框)、组合框的父级、用户控件、窗口...

标签: wpf data-binding combobox datatemplate


【解决方案1】:

我以为我已经在自己的程序中解决了这个问题,但发现它一直间歇性地弹出。终于找到问题的根源了。

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

重写它以便您只为给定事件调用一次Refresh() 将防止弹出绑定错误。

【讨论】:

  • 我的代码中只有一个手动刷新调用,但删除它可以消除所有这些错误消息。感谢您的解决方案!
  • 我有一个类似的问题,我用于项目源的集合经常更新/更改,这是我的问题的原因。我无法确认,但如果 R​​efresh() 在途中的某个地方被调用,我不会感到惊讶。
【解决方案2】:

我只想提一下,我在这个问题上苦苦挣扎了两天。最常见的建议解决方案(将 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;
    }
}

...所以我将其更改为每次都重新订阅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;
    }
}

瞧!没有更多错误:-)

【讨论】:

    【解决方案3】:

    为这个错误苦苦挣扎了几个小时,尝试了谷歌的所有解决方案,只有这个有效,从你的组合框样式中删除 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://docs.microsoft.com/en-us/dotnet/desktop/wpf/controls/combobox-styles-and-templates?view=netframeworkdesktop-4.8

    【讨论】:

      【解决方案4】:

      我不知道您是否还需要这方面的帮助,但我只是想出了一种方法让这个错误/警告消失。 在我的组合框中,我重新定义了 ItemTemplate 属性,如下所示:

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

      YourBinding 是您将用作组合框的“DisplayMemberPath”的值

      【讨论】:

      • 我早就完成了那个项目,并且不能轻易获得源代码。我认为我有一个自定义 ItemTemplate,但我不确定。不幸的是,我可能需要几个月(如果有的话)才能再次回到那个项目并进行检查。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-03
      • 2021-07-29
      • 1970-01-01
      相关资源
      最近更新 更多