namespace FluentTest.TemplateSelectors { using System; using System.ComponentModel; using System.Windows; using System.Windows.Controls; using FluentTest.Helpers; /// /// 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 TemplatesCollectionProperty = DependencyProperty.RegisterAttached("TemplatesCollection", typeof(TemplateCollection), typeof(DynamicTemplateSelector), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.OverridesInheritanceBehavior)); /// 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 [AttachedPropertyBrowsableForType(typeof(ContentControl))] public static TemplateCollection GetTemplatesCollection(DependencyObject target) { return (TemplateCollection)target.GetValue(TemplatesCollectionProperty); } /// Sets the value of the 's attached /// The element to set the property on /// The collection of s to apply to this element [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)] public static void SetTemplatesCollection(DependencyObject target, TemplateCollection value) { target.SetValue(TemplatesCollectionProperty, value); } /// /// 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 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 != null) { var templates = GetTemplatesCollection(container); if (templates != null && templates.Count != 0) { 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 var dataType = template.DataType as Type; if (dataType != null && dataType.IsInstanceOfType(item)) { //And if it is, then we return that DataTemplate return template; } } } } //If all else fails, then we go back to using the default DataTemplate return new DataTemplate(); } } }