【问题标题】:Binding Itemscontrol to ObservableCollection: extra generated item将 Itemscontrol 绑定到 ObservableCollection:额外生成的项目
【发布时间】:2016-09-09 03:02:41
【问题描述】:

ItemsControl 绑定到ObservableCollection<T> 会在运行时在控件中放置一个额外的{NewItemPlaceholder}。我怎样才能删除它?

注意 我见过posts related to this problem,但仅限于DataGrid,您可以在其中设置CanUserAddRowsIsReadOnly 属性以摆脱此项目。 ItemsControl 没有任何此类属性。

XAML

这是我的ItemsControlMyPoints 在底层 ViewModel 中是 ObservableCollection<T>):

<ItemsControl ItemsSource="{Binding MyPoints}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <Canvas />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>

  <ItemsControl.ItemContainerStyle>
    <Style TargetType="FrameworkElement">
      <Setter Property="Canvas.Left" Value="{Binding Path=X}" />
      <Setter Property="Canvas.Top" Value="{Binding Path=Y}" />
    </Style>
  </ItemsControl.ItemContainerStyle>

  <ItemsControl.ItemTemplate>
    <DataTemplate DataType="{x:Type vm:PointVM}">
      <Ellipse Width="10" Height="10" Fill="#88FF2222" />
    </DataTemplate>       
  </ItemsControl.ItemTemplate>
</ItemsControl>

这会在 0,0 处显示一个额外的点。 Live Property Explorer 显示此点已绑定到 {NewItemPlaceholder} 对象。

【问题讨论】:

  • 实际上,以这种方式从 ViewModel 添加点对我来说效果很好:MyPoints = new ObservableCollection&lt;MyPoint&gt; { new MyPoint { X = 2, Y = 3}, new MyPoint { X = 40, Y = 60} }; 您的 ObservableCollection 是否也绑定到其他地方?

标签: wpf data-binding itemscontrol


【解决方案1】:

MSDN 写道:

当实现IEditableCollectionViewCollectionView 具有 NewItemPlaceholderPosition 设置为 AtBeginningAtEnd,即 NewItemPlaceholder 被添加到集合中。 NewItemPlaceholder 总是出现在集合中;它不参与分组, 排序或过滤。

链接:MSDN

希望如果您将 NewItemPlaceholderPosition 设置为其他值,占位符将从集合中消失。

编辑:

如果您的ObservableCollection&lt;T&gt; 也被绑定到其他地方(例如:绑定到DataGrid,您必须将CanUserAddRows 设置为false),您必须处理该其他项目。它会为您的收藏添加一个新的NewItemPlaceholder

【讨论】:

  • ObservableCollection&lt;T&gt; 似乎没有实现IEditableCollectionView。还是我错过了什么?
  • 能否将ItemsControl 设置的xaml 部分添加到您的问题中?
  • 更新了我的问题。
  • 我将ObservableCollection&lt;T&gt; 更改为List&lt;T&gt; 仍然可以看到额外的项目。我实际上删除了 ItemsControl.ItemsSource 绑定的依赖属性,而是使用了与 VM 属性的直接绑定,但仍然可以在 ItemsControl 中看到不需要的项目。在这里做的差不多了。 :(
  • 尝试新建一个项目,只添加ObservableCollection&lt;T&gt;ItemsControl。那一定行得通。然后尝试构建其他正在使用该集合的 xaml 元素。
【解决方案2】:

终于来了!

花了一天时间后,结果证明解决方案很简单(尽管并不理想)。 ItemTemplateSelector 允许我根据项目类型选择模板,因此我可以创建一个简单的选择器来去除多余的项目:

public class PointItemTemplateSelector : DataTemplateSelector
{
  public override DataTemplate SelectTemplate(object item, DependencyObject container)
  {
    if (item == CollectionView.NewItemPlaceholder)
      return (container as FrameworkElement).TryFindResource("EmptyDataTemplate") as DataTemplate;
    else
      return (container as FrameworkElement).TryFindResource("MyDataTemplate") as DataTemplate;
  }
}

MyDataTemplateEmptyDataTemplate 应该在ItemsControlResources 部分中定义。 EmptyDataTemplate 不需要有任何内容。

编辑

@KAI 的猜测(见接受的答案)是正确的。我的ObservableCollection&lt;T&gt; 绑定到了导致此问题的DataGrid。我仍然会在这里保留我的答案,因为它为其他相关情况提供了解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-04
    • 2011-11-30
    • 2017-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多