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(); } } } }