WPF 集合依赖项 属性 添加重复项

WPF collection dependency property adding duplicates

我创建了一个 class,它声明了一个附加的 属性,它将保存数据模板集合:

public class DynamicTemplatesList : DependencyObject
 {
    public static readonly DependencyProperty TemplatesProperty =
            DependencyProperty.RegisterAttached("Templates", typeof(TemplateCollection), typeof(DynamicTemplatesList), new FrameworkPropertyMetadata(new TemplateCollection(), 
    FrameworkPropertyMetadataOptions.None));

    public static void SetTemplates(UIElement element, TemplateCollection collection)
        {
            element.SetValue(TemplatesProperty, collection);
        }
}

然后在xaml我设置了集合:

        <gfc:DynamicTemplatesList.Templates>
            <gfc:Template Key="{StaticResource CheckBoxFieldType}"
                                         DataTemplate="{StaticResource CheckBoxTemplate}" />
            <gfc:Template Key="{StaticResource LookupEditFieldType}"
                                         DataTemplate="{StaticResource LookupEditTemplate}" />
            <gfc:Template Key="{StaticResource TextBoxFieldType}"
                                         DataTemplate="{StaticResource TextBoxTemplate}" />
            <gfc:Template Key="{StaticResource DateEditFieldType}"
                                         DataTemplate="{StaticResource DateEditTemplate}" />
        </gfc:DynamicTemplatesList.Templates>

这似乎第一次运行良好。但是我注意到的一件事是,当我关闭 window 与此依赖关系 属性 然后再次重新打开它时, 似乎模板再次添加到集合中。

第一次,集合中会有4个模板,第二次是8个,依此类推。谁能向我解释这里发生了什么?

我怀疑是因为依赖属性的静态性质导致值被重复,如果是这种情况,谁能告诉我一个解决方案来防止附加集合 属性 添加重复项?

问题是您将 new TemplateCollection() 设置为依赖项 属性 的默认值。这个 "static" 集合实例将在您使用 属性 之前使用而没有分配它时使用,就像您在 XAML.

中所做的那样

除了 null 之外,您永远不应使用任何其他内容作为包含可修改集合的依赖项 属性 的默认值。

public class DynamicTemplatesList
{
    public static readonly DependencyProperty TemplatesProperty =
        DependencyProperty.RegisterAttached(
            "Templates",
            typeof(TemplateCollection),
            typeof(DynamicTemplatesList));

     public static TemplateCollection GetTemplates(UIElement element)
     {
         return (TemplateCollection)element.GetValue(TemplatesProperty);
     }

     public static void SetTemplates(UIElement element, TemplateCollection collection)
     {
         element.SetValue(TemplatesProperty, collection);
     }
}

现在在 XAML 中显式分配一个 TemplateCollection 实例,如下所示:

<gfc:DynamicTemplatesList.Templates>
    <gfc:TemplateCollection>
        <gfc:Template ... />
        <gfc:Template ... />
        <gfc:Template ... />
        <gfc:Template ... />
    </gfc:TemplateCollection>
</gfc:DynamicTemplatesList.Templates>

请注意,如果您的 class 仅注册附加属性,则无需派生自 DependencyObject