设置ListView ItemsPanel重复项目

时间:2016-06-03 19:26:09

标签: c# wpf xaml listview

我的应用程序中有自定义控件。其中一个依赖项属性是ObservableCollection<ToggleButton>

public ObservableCollection<ToggleButton> HeaderButtons
{
    get { return (ObservableCollection<ToggleButton>)GetValue(HeaderButtonsProperty); }
    set { SetValue(HeaderButtonsProperty, value); }
}

public static readonly DependencyProperty HeaderButtonsProperty = DependencyProperty.Register("HeaderButtons", typeof(ObservableCollection<ToggleButton>), typeof(Expandable), new PropertyMetadata(new ObservableCollection<ToggleButton>()));

然后我将它们放在ListView中的Generic.xaml

<ListView ItemsSource="{TemplateBinding HeaderButtons}">
    <ListView.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel Orientation="Horizontal"/>
       </ItemsPanelTemplate>
   </ListView.ItemsPanel>
</ListView>

......并像这样使用它:

<controls:MyControl.HeaderButtons>
    <ToggleButton x:Name="FilterButton">
        <Image Source="/Assets/Icons/Empty Filter-512.png" Height="15" Width="15"/>
    </ToggleButton>
</controls:MyControl.HeaderButtons>

但是,我一直以一个重复的项目结束:

Duplicate item

我无法弄清楚该项目是如何到达那里的。我可以通过删除我的自定义ListView.ItemsPanel来修复它,但当然这会使我的项目垂直流动,从而击败整个目的。任何人都可以看到为什么这会重复该项目吗?

编辑:为了进一步的兴趣,如果我进入实时视觉树我可以看到两个按钮都有名称“FilterButton”。当然,这应该是不可能的。

编辑:以下是ContentPresenter的{​​{1}}:

MainWindow

<ContentPresenter Content="{Binding CurrentControl, Mode=OneWay}" Grid.Row="1" Grid.Column="1"/> 设置为CurrentControl的实例:

UserControl

1 个答案:

答案 0 :(得分:2)

问题的根源是HeaderButtonsProperty的默认值 - 您使用new PropertyMetadata(new ObservableCollection<ToggleButton>())设置了一个问题。与您的预期相反,它不会为您的控件的每个实例创建一个集合实例,而是在所有控件上共享一个实例。

然后使用此XAML语法:

<controls:MyControl.HeaderButtons>
    <ToggleButton (...) />
</controls:MyControl.HeaderButtons>

不会将新集合分配给HeadersButton属性,而是将指定项添加到现有属性中。因此,每次执行此部分代码时,都会将ToggleButton的新副本添加到所有控件共享的单个集合中。

要解决此问题,您应该从HeaderButtonsProperty的元数据中删除默认值,并在控件的构造函数中指定一个新的集合实例 - 这样每个控件实例都会拥有它#&# 39;自己的独立收藏。