将 Itemscontrol 绑定到 ObservableCollection:额外生成的项目
Binding Itemscontrol to ObservableCollection: extra generated item
将 ItemsControl
绑定到 ObservableCollection<T>
会在运行时在控件中放置一个额外的 {NewItemPlaceholder}
。我怎样才能删除它?
N.B. 我见过 posts related to this problem 但这些仅限于 DataGrid
,您可以在其中设置 CanUserAddRows
或 IsReadOnly
属性去掉这个项目。 ItemsControl
没有任何这样的 属性。
XAML
这是我的 ItemsControl
(MyPoints
在底层 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 属性 Explorer 显示此点已绑定到 {NewItemPlaceholder}
对象。
MSDN 写道:
When a CollectionView
that implements IEditableCollectionView
has
NewItemPlaceholderPosition
set to AtBeginning
or AtEnd
, the
NewItemPlaceholder
is added to the collection. The NewItemPlaceholder
always appears in the collection; it does not participate in grouping,
sorting, or filtering.
Link: MSDN
希望如果您将 NewItemPlaceholderPosition
设置为其他内容,占位符将从 collection 中消失。
编辑:
如果你的 ObservableCollection<T>
也被绑定到其他地方(例如:绑定到 DataGrid
,你必须将 CanUserAddRows
设置为 false),你必须处理那其他项目。它会添加一个新的 NewItemPlaceholder
到你的 collection.
终于终于!
花了一天时间,解决方案很简单(虽然不理想)。 ItemTemplateSelector
允许我 select 基于项目类型的模板,因此我可以创建一个简单的 select 或者删除额外的项目:
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;
}
}
MyDataTemplate
和 EmptyDataTemplate
应该在 ItemsControl
的 Resources
部分定义。 EmptyDataTemplate
不需要有任何内容。
编辑
@KAI 的猜测(参见接受的答案)是正确的。我的 ObservableCollection<T>
绑定到导致此问题的 DataGrid
。我仍然会在这里保留我的答案,因为它为其他相关情况提供了解决方案。
将 ItemsControl
绑定到 ObservableCollection<T>
会在运行时在控件中放置一个额外的 {NewItemPlaceholder}
。我怎样才能删除它?
N.B. 我见过 posts related to this problem 但这些仅限于 DataGrid
,您可以在其中设置 CanUserAddRows
或 IsReadOnly
属性去掉这个项目。 ItemsControl
没有任何这样的 属性。
XAML
这是我的 ItemsControl
(MyPoints
在底层 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 属性 Explorer 显示此点已绑定到 {NewItemPlaceholder}
对象。
MSDN 写道:
When a
CollectionView
that implementsIEditableCollectionView
hasNewItemPlaceholderPosition
set toAtBeginning
orAtEnd
, theNewItemPlaceholder
is added to the collection. TheNewItemPlaceholder
always appears in the collection; it does not participate in grouping, sorting, or filtering.
Link: MSDN
希望如果您将 NewItemPlaceholderPosition
设置为其他内容,占位符将从 collection 中消失。
编辑:
如果你的 ObservableCollection<T>
也被绑定到其他地方(例如:绑定到 DataGrid
,你必须将 CanUserAddRows
设置为 false),你必须处理那其他项目。它会添加一个新的 NewItemPlaceholder
到你的 collection.
终于终于!
花了一天时间,解决方案很简单(虽然不理想)。 ItemTemplateSelector
允许我 select 基于项目类型的模板,因此我可以创建一个简单的 select 或者删除额外的项目:
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;
}
}
MyDataTemplate
和 EmptyDataTemplate
应该在 ItemsControl
的 Resources
部分定义。 EmptyDataTemplate
不需要有任何内容。
编辑
@KAI 的猜测(参见接受的答案)是正确的。我的 ObservableCollection<T>
绑定到导致此问题的 DataGrid
。我仍然会在这里保留我的答案,因为它为其他相关情况提供了解决方案。