using System;
using System.Windows;
using System.Windows.Controls;
namespace InABox.WPF
{
public static class TemplateGenerator
{
///
/// Creates a data-template that uses the given delegate to create new instances.
///
public static DataTemplate CreateDataTemplate(Func factory)
{
if (factory == null)
throw new ArgumentNullException("factory");
var frameworkElementFactory = new FrameworkElementFactory(typeof(_TemplateGeneratorControl));
frameworkElementFactory.SetValue(_TemplateGeneratorControl.FactoryProperty, factory);
var dataTemplate = new DataTemplate(typeof(DependencyObject));
dataTemplate.VisualTree = frameworkElementFactory;
return dataTemplate;
}
///
/// Creates a control-template that uses the given delegate to create new instances.
///
public static ControlTemplate CreateControlTemplate(Type controlType, Func factory)
{
if (controlType == null)
throw new ArgumentNullException("controlType");
if (factory == null)
throw new ArgumentNullException("factory");
var frameworkElementFactory = new FrameworkElementFactory(typeof(_TemplateGeneratorControl));
frameworkElementFactory.SetValue(_TemplateGeneratorControl.FactoryProperty, factory);
var controlTemplate = new ControlTemplate(controlType);
controlTemplate.VisualTree = frameworkElementFactory;
return controlTemplate;
}
private sealed class _TemplateGeneratorControl :
ContentControl
{
internal static readonly DependencyProperty FactoryProperty = DependencyProperty.Register("Factory", typeof(Func),
typeof(_TemplateGeneratorControl), new PropertyMetadata(null, _FactoryChanged));
private static void _FactoryChanged(DependencyObject instance, DependencyPropertyChangedEventArgs args)
{
var control = (_TemplateGeneratorControl)instance;
var factory = (Func)args.NewValue;
if (factory != null)
control.Content = factory();
}
}
}
}