【问题标题】:WPF collection dependency property adding duplicatesWPF 集合依赖属性添加重复项
【发布时间】:2017-07-03 17:49:13
【问题描述】:

我创建了一个类,它声明了一个附加属性,该属性将包含一个数据模板集合:

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>

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

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

我怀疑这是因为依赖属性的静态特性导致值被重复,如果是这种情况,任何人都可以指出一个解决方案来防止附加的集合属性添加重复项吗?

【问题讨论】:

    标签: c# wpf xaml dependency-properties


    【解决方案1】:

    问题是您将new TemplateCollection() 设置为依赖属性的默认值。只要您使用您的属性而不分配它,就会使用这个“静态”集合实例,就像您在 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>
    

    请注意,如果您的类仅注册附加属性,则不需要从 DependencyObject 派生。

    【讨论】:

    • 当我加载相关的 xaml 控件时,如果我将依赖属性的默认值从 new FrameworkPropertyMetadata(new TemplateCollection(), FrameworkPropertyMetadataOptions.None) 更改为 null,它会引发 null 异常,说明模板属性为空。
    • 另一件事是我不需要从 DependencyObject 派生来访问 SetCurrentValue 方法吗?
    • 是的,我确实对构造函数进行了更改
    • 很抱歉给您带来了困惑。我已经编辑了答案。您必须先将 TemplateCollection 的新实例分配给该属性,然后才能使用它。
    • 是的,我在 XAML 中以相同的方式明确分配。我现在遇到的问题是我似乎无法在我的 DataTemplateSelector 中检索这些模板:
    猜你喜欢
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 2017-04-01
    • 2014-07-29
    • 2014-05-23
    相关资源
    最近更新 更多