using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; namespace JD.SceneExplorer.TemplateSelector { /// /// /// Provides a means to specify DataTemplates to be selected from within WPF code /// public class DynamicTemplateSelector : DataTemplateSelector { /// /// Generic attached property specifying s /// used by the /// /// /// This attached property will allow you to set the templates you wish to be available whenever /// a control's TemplateSelector is set to an instance of /// public static readonly DependencyProperty TemplatesProperty = DependencyProperty.RegisterAttached("Templates", typeof(TemplateCollection), typeof(DataTemplateSelector), new FrameworkPropertyMetadata(new TemplateCollection(), FrameworkPropertyMetadataOptions.Inherits)); /// /// Gets the value of the 's attached /// /// The who's attached template's property you wish to retrieve /// The templates used by the givem /// when using the public static TemplateCollection GetTemplates(UIElement element) { return (TemplateCollection)element.GetValue(TemplatesProperty); } /// /// Sets the value of the 's attached /// /// The element to set the property on /// The collection of s to apply to this element public static void SetTemplates(UIElement element, TemplateCollection collection) { element.SetValue(TemplatesProperty, collection); } /// /// /// Overriden base method to allow the selection of the correct DataTemplate /// /// The item for which the template should be retrieved /// The object containing the current item /// The to use when rendering the public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.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 (var 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); } } /// /// /// Holds a collection of items /// for application as a control's DataTemplate. /// public class TemplateCollection : List