2015-11-09 35 views
1

我在我的WPF应用程序中使用DataTemplateSelector。在运行时它可以很好地工作,但是当使用XAML编辑器时会抛出异常并且不显示预览。在XAML Designer中DataTemplateSelector的类型初始化失败

enter image description here

我的选择是这样的:

public class DynamicTemplateSelector : DataTemplateSelector 
{ 
    public static readonly DependencyProperty TemplatesProperty = DependencyProperty.RegisterAttached("Templates", typeof(TemplateCollection), typeof(DataTemplateSelector), new FrameworkPropertyMetadata(new TemplateCollection(), FrameworkPropertyMetadataOptions.Inherits)); 

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

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

    /// <summary> 
    /// Overriden base method to allow the selection of the correct DataTemplate 
    /// </summary> 
    /// <param name="item">The item for which the template should be retrieved</param> 
    /// <param name="container">The object containing the current item</param> 
    /// <returns>The <see cref="DataTemplate"/> to use when rendering the <paramref name="item"/></returns> 
    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     ////This should ensure that the item we are getting is in fact capable of holding our property 
     ////before we attempt to retrieve it. 
     if (!(container is UIElement)) 
     { 
      return base.SelectTemplate(item, container); 
     } 

     ////First, we gather all the templates associated with the current control through our dependency property 
     TemplateCollection templates = GetTemplates(container as UIElement); 
     if (templates == null || templates.Count == 0) 
     { 
      base.SelectTemplate(item, container); 
     } 

     ////Then we go through them checking if any of them match our criteria 
     foreach (Template template in templates) 
     { 
      ////In this case, we are checking whether the type of the item 
      ////is the same as the type supported by our DataTemplate 
      if (template.Value.IsInstanceOfType(item)) 
      { 
       ////And if it is, then we return that DataTemplate 
       return template.DataTemplate; 
      } 
     } 

     ////If all else fails, then we go back to using the default DataTemplate 
     return base.SelectTemplate(item, container); 
    } 
} 

如果试图用DesignerProperties.IsInDesignTool国旗在我的选择,但没有成功......

public class TemplateCollection : List<Template> 
    { 
    } 




    public class Template : DependencyObject 
    { 
    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(Type), typeof(Template)); 

    public static readonly DependencyProperty DataTemplateProperty = DependencyProperty.Register("DataTemplate", typeof(DataTemplate), typeof(Template)); 

public Type Value 
{ 
    get 
    { 
    return (Type)this.GetValue(ValueProperty); 
    } 

    set 
    { 
    this.SetValue(ValueProperty, value); 
    } 
} 

public DataTemplate DataTemplate 
{ 
    get 
    { 
    return (DataTemplate)this.GetValue(DataTemplateProperty); 
    } 

    set 
    { 
    this.SetValue(DataTemplateProperty, value); 
    } 
} 

}

+0

您将'TargetType'设置为'ContentControl'。 'ContentControl'不会自动从你自己的对象中获取属性。 – bars222

+0

好的,但我怎么设置呢?感谢您的帮助... – Kingpin

+0

通常,使用可变引用类型来初始化默认依赖项属性值并不是一个好主意,它可能会导致一堆问题,并且还会在设计器中导致问题。在依赖项属性声明中传递'null'而不是'TemplateCollection()',如果它不解决'TemplateCollection'类发布后的问题。 –

回答

1

这是问题:

public static readonly DependencyProperty TemplatesProperty = 
DependencyProperty.RegisterAttached("Templates", typeof(TemplateCollection), 
typeof(DataTemplateSelector), new FrameworkPropertyMetadata(
new TemplateCollection(), FrameworkPropertyMetadataOptions.Inherits)); 

正在注册的基础类DataTemplateSelector,而不是您正在使用的属性,它似乎打破设计类在XAML DynamicTemplateSelector附加属性。