自定义控件依赖项属性集合,计算嵌套控件项

时间:2013-11-03 17:38:54

标签: wpf

我创建了两个自定义控件。 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

请建议我在哪里做错了。

1 个答案:

答案 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>()); 
}