简体   繁体   English

在DataTemplateSelector上使用DataTemplates的WPF字典的键始终为空值

[英]WPF Dictionary using DataTemplates on a DataTemplateSelector always having a null value for the key

I have a dictionary on my DataTemplateSelector that holds a list of datatemplates. 我的DataTemplateSelector上有一个字典,其中包含一个数据模板列表。 The constructor creates the dictionary holding DataTemplate properties as the value but the dictionary is always reflecting null values, meanwhile I can look at the property when the SelectTemplate is called and the property has the correct DataTemplate in it. 构造函数创建的字典将DataTemplate属性保留为值,但是字典始终反映空值,同时我可以在调用SelectTemplate并且属性中包含正确的DataTemplate时查看该属性 What is going on that the dictionary (which I thought was reference type) always show the initial 'null' value when the dictionary was created and not the object? 字典(我认为是引用类型)在创建字典时始终显示初始“空”值,而不是对象时发生了什么?

Is there anyway I can get this to work without scrapping the dictionary and using a switch? 无论如何,我可以在不删除字典和使用开关的情况下使它正常工作吗? I was using it to avoid a giant switch statement, but I'm not sure why this isn't working. 我用它来避免巨大的switch语句,但是我不确定为什么它不起作用。

View: 视图:

  <selector:NodePropertyGridTemplateSelector x:Key="sel">
     <selector:NodePropertyGridTemplateSelector.PageLoadedDataTemplate>
                <DataTemplate>
                   ...
                </DataTemplate>
            </selector:NodePropertyGridTemplateSelector.PageLoadedDataTemplate>
    </selector:NodePropertyGridTemplateSelector>

DataTemplateSelector: DataTemplateSelector:

 public class NodePropertyGridTemplateSelector : DataTemplateSelector
{
    private Dictionary<string, DataTemplate> _dictionary;

    public NodePropertyGridTemplateSelector()
    {
        _dictionary = new Dictionary<string, DataTemplate>();
        _dictionary.Add("PageLoaded", PageLoadedDataTemplate);
    }

    public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
    {
        if (item != null)
        {
            return (DataTemplate)_dictionary["PageLoaded"];

            //return PageLoadedDataTemplate;  this works fine. The above dictionary is null for the value at this key.
        }
        return base.SelectTemplate(item, container);
    }

    public DataTemplate PageLoadedDataTemplate { get; set; }

When the constructor of NodePropertyGridTemplateSelector executes, the content of the property PageLoadedDataTemplate is still null , and this null value is being added to the dictionary. 执行NodePropertyGridTemplateSelector的构造方法时,属性PageLoadedDataTemplate的内容仍为null ,并且将此null值添加到字典中。

Later - after the constructor returned and the NodePropertyGridTemplateSelector instance has been created - another value (a reference to a DataTemplate object) is being assigned to PageLoadedDataTemplate . 稍后-在返回构造函数并创建NodePropertyGridTemplateSelector实例之后,将另一个值(对DataTemplate对象的引用)分配给PageLoadedDataTemplate However, while the content of the PageLoadedDataTemplate property is now different, the content stored in the dictionary still remains null . 但是,尽管PageLoadedDataTemplate属性的内容现在有所不同,但存储在字典中的内容仍保持为null

To have the dictionary always reflect the current content of the PageLoadedDataTemplate property, update the dictionary in the property setter. 要使字典始终反映PageLoadedDataTemplate属性的当前内容,请在属性设置器中更新字典。 By doing so, the getter must also be implemented - which should simply fetch and return the respective value stored in the dictionary. 这样,还必须实现getter-它应该简单地获取并返回存储在字典中的各个值。

public class NodePropertyGridTemplateSelector : DataTemplateSelector
{
    private readonly Dictionary<string, DataTemplate> _dictionary = new Dictionary<string, DataTemplate>();

    public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
    {
        if (item != null)
        {
            DataTemplate dt;
            if (_dictionary.TryGetValue("PageLoaded", out dt))
                return dt;
        }
        return base.SelectTemplate(item, container);
    }

    public DataTemplate PageLoadedDataTemplate
    {
        get
        {
            DataTemplate dt;
            return _dictionary.TryGetValue("PageLoaded", out dt) ? dt : null;
        }

        set
        {
            if (value == null) _dictionary.Remove("PageLoaded");
            else _dictionary["PageLoaded"] = value;
        }
    }
}

The example code given here avoids null values being stored in the dictionary. 此处给出的示例代码避免将值存储在字典中。 If it the dictionary (or the property) should/can be accessed from different threads in a concurrent manner, it might be safer to use ConcurrentDictionary . 如果应该(可以)并发地从不同线程访问字典(或属性),则使用ConcurrentDictionary可能更安全。

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

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