多个实例依赖属性

时间:2016-01-14 03:59:24

标签: c# wpf

所以我得到了一个我不喜欢的行为,我不知道如何解决它,假设我有一个简单的用户控件DependencyProperty,如下所示:

public static readonly DependencyProperty CollectionProperty =
    DependencyProperty.Register(
        "Collection", 
        typeof (ObservableCollection<string>), 
        typeof (TestControl),
        new PropertyMetadata(new ObservableCollection<string>())); 

public ObservableCollection<string> Collection
{
    get { return (ObservableCollection<string>) GetValue(CollectionProperty); }
    set { SetValue(CollectionProperty, value); }
}

然后我创建了2个不同的控件实例,注意我在一个控件中添加了“Hello”,在第二个控件中添加了“World”,用户控件只包含一个ItemsControl,显示我们创建的DependencyProperty。 / p>

<chartsTest:TestControl Background="Red">
    <chartsTest:TestControl.Collection>
        <system:String>hello</system:String>
    </chartsTest:TestControl.Collection>
</chartsTest:TestControl>
<chartsTest:TestControl Background="Blue">
    <chartsTest:TestControl.Collection>
        <system:String>World</system:String>
    </chartsTest:TestControl.Collection>
</chartsTest:TestControl>

我在两个控件中都获得了“Hello World”:

enter image description here

我想我明白这是因为defualt集合被初始化为一个静态变量,好的但是我如何为每个实例初始化它?

我知道如果我使用这个sintax它会起作用:

<chartsTest:TestControl Background="Blue" x:Name="TestControl" 
                        Collection="{Binding Path=TestProperty}">                
</chartsTest:TestControl>

有没有办法让两者兼顾? 我希望我足够清楚,这是一个代表我的问题的简单例子。

2 个答案:

答案 0 :(得分:2)

请记住,任何DP都应声明为静态,因此应初始化该值。

在UserControl(TestControl)的构造函数上,初始化Collection属性:

更新

SetCurrentValue(CollectionProperty, new List<string>());

我们可以通过以下方式测试:

<local:TestControl Background="Red">
   <local:TestControl.Collection>
          <system:String>hello</system:String>
    </local:TestControl.Collection>
</local:TestControl>

<local:TestControl Background="Blue">
     <system:String>world</system:String>
</local:TestControl>

<local:TestControl Background="Green" Collection="{Binding List}"/>

顺便说一下,如果您没有收听列表中的项目更改,我建议改用List。

答案 1 :(得分:1)

此行为是设计使然,您没有显式创建ObservableCollection,因此依赖项属性都共享您在注册时创建的默认属性。有几种方法可以解决这个问题,但最简单的方法是将默认值设置为null并为ObservableCollection创建一个包装类:

public class StringObservableCollection : ObservableCollection<string>
{
}

然后在XAML中使用它来包装列表元素:

    <chartsTest:TestControl Background="Red">
        <chartsTest:TestControl.Collection>
            <local:StringObservableCollection>
                <system:String>hello</system:String>
            </local:StringObservableCollection>
        </chartsTest:TestControl.Collection>
    </chartsTest:TestControl>
    <chartsTest:TestControl Background="Blue">
        <chartsTest:TestControl.Collection>
            <local:StringObservableCollection>                  
                <system:String>World</system:String>
            </local:StringObservableCollection>
        </chartsTest:TestControl.Collection>
    </chartsTest:TestControl>

或者,您可以在tgpdyk已经指出的构造函数中设置值。更多详情here