多个用户控件共享集合依赖属性

14
我已经实现了一个基于列表框的自定义用户控件。它有一个依赖属性,类型是一个集合。当我在窗口中只有一个用户控件实例时,它可以正常工作,但是如果我有多个实例,它们会共享集合依赖属性。以下是一个示例说明这一点。
我的用户控件称为SimpleList:
<UserControl x:Class="ItemsTest.SimpleList"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Name="_simpleList">
    <StackPanel>
        <TextBlock Text="{Binding Path=Title, ElementName=_simpleList}" />
        <ListBox 
            ItemsSource="{Binding Path=Numbers, ElementName=_simpleList}">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
        </ListBox>
    </StackPanel>    
</UserControl>

后台代码:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;

namespace ItemsTest
{
    public partial class SimpleList : UserControl
    {
        public SimpleList()
        {
            InitializeComponent();
        }

        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }

        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register("Title", typeof(string), typeof(SimpleList), new UIPropertyMetadata(""));


        public List<int> Numbers 
        {
            get { return (List<int> )GetValue(NumbersProperty); }
            set { SetValue(NumbersProperty, value); }
        }

        public static readonly DependencyProperty NumbersProperty =
            DependencyProperty.Register("Numbers ", typeof(List<int>), typeof(SimpleList), new UIPropertyMetadata(new List<int>()));
    }
}

我使用的方式如下:

   <StackPanel>
        <ItemsTest:SimpleList Title="First">
            <ItemsTest:SimpleList.Numbers>
                <sys:Int32>1</sys:Int32>
                <sys:Int32>2</sys:Int32>
                <sys:Int32>3</sys:Int32>
            </ItemsTest:SimpleList.Numbers>
        </ItemsTest:SimpleList>
        <ItemsTest:SimpleList Title="Second">
            <ItemsTest:SimpleList.Numbers>
                <sys:Int32>4</sys:Int32>
                <sys:Int32>5</sys:Int32>
                <sys:Int32>6</sys:Int32>
            </ItemsTest:SimpleList.Numbers>
        </ItemsTest:SimpleList>
    </StackPanel>

我期望以下内容会出现在我的窗口:

First
123
Second
456

但是我看到的是:

First
123456
Second
123456

如何使多个SimpleList不共享它们的Numbers集合?

1个回答

24

找到了答案,构造函数需要初始化属性,而不是让静态属性自己完成:

public SimpleList()
{
   SetValue(NumbersProperty, new List<int>()); 

   InitializeComponent();
}

集合类型依赖属性


1
我简直不敢相信。我已经浪费了好几个小时还是找不到答案。 我都要把头发都拔光了。谢谢 :) 虽然我相信这是依赖机制中的一个 bug。 - Chen
这仍然是一个问题,但由于这个问题/答案,解决方案变得轻松无痛... - PScr
这归结于默认值和引用类型 DP 的工作方式:https://msdn.microsoft.com/zh-cn/library/aa970563(v=vs.100).aspx - PScr
最好使用SetCurrentValue,这样属性仍然可以从Style中设置。 - Grx70
这一定是更普遍的问题!太丢人了!我花了近5个小时试图弄清楚为什么我的控件没有正常工作..... - GeorgiG

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