简体   繁体   English

多实例依赖属性

[英]Multiple instances dependency property

So I am getting a behavior I don't like and I don't see how to solve it, let's say I have a simple user control with a DependencyProperty as follows:所以我得到了一个我不喜欢的行为,我不知道如何解决它,假设我有一个带有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); }
}

Then I created 2 diferent instances of this control, notice That I added "Hello" in one control and "World" in the second one, the user control only contains a ItemsControl showing the DependencyProperty we created.然后我创建了这个控件的 2 个不同的实例,注意我在一个控件中添加了“Hello”,在第二个控件中添加了“World”,用户控件只包含一个显示我们创建的DependencyProperty的 ItemsControl。

<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>

And I get "Hello World" in both controls:我在两个控件中都得到了“Hello World”:

在此处输入图片说明

I think I understand that this happens because the defualt collection is being initialized as a static variable, ok but then how do I initialize it for each instance?我想我明白这是因为 defualt 集合被初始化为一个静态变量,好的但是我如何为每个实例初始化它?

I know that if I use this sintax it will work:我知道如果我使用这个 sintax 它会起作用:

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

Is there any way to make both work?有没有办法让两者都起作用? I hope I am clear enough, this is a simple example tryin to represent my problem.我希望我足够清楚,这是一个试图代表我的问题的简单示例。

Remember that any DP should be declared as static so the value should be initialized.请记住,任何 DP 都应声明为静态,因此应初始化该值。

On the constructor of your UserControl (TestControl), initialize your Collection property:在 UserControl (TestControl) 的构造函数上,初始化 Collection 属性:

Update:更新:

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

We can test it by:我们可以通过以下方式进行测试:

<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}"/>

By the way if you are not listening with item change of your list, I suggest to use a List instead.顺便说一下,如果您不听列表的项目更改,我建议改用列表。

This behaviour is by design, you're not explicitly creating an ObservableCollection so the dependency properties all share the default one you're creating when you register it.此行为是设计使然,您没有显式创建 ObservableCollection,因此依赖属性都共享您在注册时创建的默认属性。 There are several ways to solve this but probably the easiest is to to set the default to null and create a wrapper class for ObservableCollection:有几种方法可以解决这个问题,但最简单的方法可能是将默认值设置为 null 并为 ObservableCollection 创建一个包装类:

public class StringObservableCollection : ObservableCollection<string>
{
}

Then use this in your XAML to wrap your list elements:然后在您的 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>

Alternatively you can set the value in the constructor as tgpdyk has already pointed out.或者,您可以在构造函数中设置值,正如 tgpdyk 已经指出的那样。 More details here .更多细节在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM