我创建了两个自定义控件。 1. LeafControl 2- LeafItemControl。 在LeafControl中,我创建了一个“List”类型的依赖属性作为“Items”。
同样在LeafItemControl中,我还暴露了一个ContentControl类型的依赖属性调用“ItemDetails”。
<!---Base Custom Control "LeafControl"-->
<uc:LeafControlItem.ItemDetails> <!--"ItemDetails" is a Dependency Property of type "LeafControl" in "LeafControlItem" custom control -->
<uc:LeafControl> <!--Nested Control of same type ???-->
<uc:LeafControl.Items>
<uc:LeafControlItem Level="Some Type">
<uc:LeafControlItem.ItemContent>
<GroupBox BorderThickness="0">
<StackPanel Orientation="Horizontal">
<TextBox Text="Property"></TextBox>
</StackPanel>
</GroupBox>
</uc:LeafControlItem.ItemContent>
</uc:LeafControlItem>
<uc:LeafControlItem Level="Variable">
<uc:LeafControlItem.ItemContent>
<GroupBox BorderThickness="0">
<StackPanel Orientation="Horizontal">
<TextBox Text="Ellipse2.Top"></TextBox>
</StackPanel>
</GroupBox>
</uc:LeafControlItem.ItemContent>
</uc:LeafControlItem>
</uc:LeafControl.Items>
</uc:LeafControl>
</uc:LeafControlItem.ItemDetails>
</uc:LeafControlItem>
当我尝试访问基本自定义控件中的“项目”时。所有的儿童自定义控件都添加了为什么?我应该怎么做,以便每个自定义控件对象(基本和子)有单独的“项目”。
我在Base Custom Control中使用了Dependency Property,如下所示:
#region LeafControlItemCollection
public List<LeafControlItem> Items
{
get { return (List<LeafControlItem>)GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register(
"Items", typeof(List<LeafControlItem>), typeof(LeafControl),
new FrameworkPropertyMetadata(new List<LeafControlItem>(), null, null)
);
#endregion
请建议我在哪里做错了。
答案 0 :(得分:3)
问题出现在依赖属性标识符的声明中,即ItemsProperty
。您提供了default value as new List<LeafControlItem>()
。通过这样做,您已经在包装下创建了singleton instance for your list
。
读出它here,它描述了与列表DP的默认初始化相遇的完全相同的问题。从该链接引用 -
如果您的属性是引用类型,则指定的默认值 依赖项属性元数据不是每个实例的默认值; 相反,它是一个适用于所有实例的默认值 类型。因此,您必须小心不要使用单数静态 集合属性元数据定义的集合作为工作 新创建的类型实例的默认值。相反,你 必须确保您故意将集合值设置为a unique(instance)集合作为类构造函数逻辑的一部分。 否则你将创建一个无意的单例类。
将默认值指定为new List<LeafControlItem>()
,使LeafControl
的所有实例共享同一个列表实例。因此,该列表中对象的任何添加和删除都将反映在LeafControl的所有实例中。所以,实际上你已经为LeafControl的所有实例创建了单例列表。
首先,您应该避免在默认值中指定新列表 -
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register(
"Items", typeof(List<LeafControlItem>), typeof(LeafControl));
其次,您应该通过在ListControl类的构造函数中设置它来将其初始化为新列表,以便每个实例都有自己的列表共享 -
public LeafControl()
{
SetValue(ItemsPropertyKey, new List<LeafControlItem>());
}