124 lines
5.8 KiB
C#
124 lines
5.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
|
|
namespace JD.SceneExplorer.TemplateSelector
|
|
{
|
|
/// <inheritdoc />
|
|
/// <summary>
|
|
/// Provides a means to specify DataTemplates to be selected from within WPF code
|
|
/// </summary>
|
|
public class DynamicTemplateSelector : DataTemplateSelector
|
|
{
|
|
/// <summary>
|
|
/// Generic attached property specifying <see cref="Template"/>s
|
|
/// used by the <see cref="DynamicTemplateSelector"/>
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// 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 <see cref="DynamicTemplateSelector"/>
|
|
/// </remarks>
|
|
public static readonly DependencyProperty TemplatesProperty =
|
|
DependencyProperty.RegisterAttached("Templates", typeof(TemplateCollection), typeof(DataTemplateSelector),
|
|
new FrameworkPropertyMetadata(new TemplateCollection(), FrameworkPropertyMetadataOptions.Inherits));
|
|
|
|
|
|
/// <summary>
|
|
/// Gets the value of the <paramref name="element"/>'s attached <see cref="TemplatesProperty"/>
|
|
/// </summary>
|
|
/// <param name="element">The <see cref="UIElement"/> who's attached template's property you wish to retrieve</param>
|
|
/// <returns>The templates used by the givem <paramref name="element"/>
|
|
/// when using the <see cref="DynamicTemplateSelector"/></returns>
|
|
public static TemplateCollection GetTemplates(UIElement element)
|
|
{
|
|
return (TemplateCollection)element.GetValue(TemplatesProperty);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the value of the <paramref name="element"/>'s attached <see cref="TemplatesProperty"/>
|
|
/// </summary>
|
|
/// <param name="element">The element to set the property on</param>
|
|
/// <param name="collection">The collection of <see cref="Template"/>s to apply to this element</param>
|
|
public static void SetTemplates(UIElement element, TemplateCollection collection)
|
|
{
|
|
element.SetValue(TemplatesProperty, collection);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
/// <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="T:System.Windows.DataTemplate" /> to use when rendering the <paramref name="item" /></returns>
|
|
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);
|
|
}
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
/// <summary>
|
|
/// Holds a collection of <see cref="T:JD.SceneExplorer.TemplateSelector.Template" /> items
|
|
/// for application as a control's DataTemplate.
|
|
/// </summary>
|
|
public class TemplateCollection : List<Template>
|
|
{
|
|
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
/// <summary>
|
|
/// Provides a link between a value and a <see cref="P:JD.SceneExplorer.TemplateSelector.Template.DataTemplate" />
|
|
/// for the <see cref="T:JD.SceneExplorer.TemplateSelector.DynamicTemplateSelector" />
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// In this case, our value is a <see cref="T:System.Type" /> which we are attempting to match
|
|
/// to a <see cref="P:JD.SceneExplorer.TemplateSelector.Template.DataTemplate" />
|
|
/// </remarks>
|
|
public class Template : DependencyObject
|
|
{
|
|
/// <summary>
|
|
/// Provides the value used to match this <see cref="DataTemplate"/> to an item
|
|
/// </summary>
|
|
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(Type), typeof(Template));
|
|
|
|
/// <summary>
|
|
/// Provides the <see cref="DataTemplate"/> used to render items matching the <see cref="Value"/>
|
|
/// </summary>
|
|
public static readonly DependencyProperty DataTemplateProperty =
|
|
DependencyProperty.Register("DataTemplate", typeof(DataTemplate), typeof(Template));
|
|
|
|
/// <summary>
|
|
/// Gets or Sets the value used to match this <see cref="DataTemplate"/> to an item
|
|
/// </summary>
|
|
public Type Value
|
|
{ get { return (Type)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } }
|
|
|
|
/// <summary>
|
|
/// Gets or Sets the <see cref="DataTemplate"/> used to render items matching the <see cref="Value"/>
|
|
/// </summary>
|
|
public DataTemplate DataTemplate
|
|
{ get { return (DataTemplate)GetValue(DataTemplateProperty); } set { SetValue(DataTemplateProperty, value); } }
|
|
}
|
|
}
|