How do I create a datatemplate with content programmatically?
If for whatever reason you need to create a DataTemplate
programmatically you would do:
XAML:
<Grid x:Name="myGrid"> <ContentControl ContentTemplate="{DynamicResource lightGreenRectangle}" /></Grid>
Somewhere in your code:
public static DataTemplate CreateRectangleDataTemplate() { var rectangleFactory = new FrameworkElementFactory(typeof(Rectangle)); rectangleFactory.SetValue(Shape.FillProperty, new SolidColorBrush(System.Windows.Media.Colors.LightGreen)); return new DataTemplate { VisualTree = rectangleFactory, }; } public static void AddRectangleTemplateToResources(FrameworkElement element) { element.Resources.Add("lightGreenRectangle", CreateRectangleDataTemplate()); }
Then you just need to add the DataTemplate
to a ResourceDictionary
so it can be used. For example, in the code behind:
public MainWindow() { InitializeComponent(); AddRectangleTemplateToResources(myGrid); }
Hope this helps!
Using the following helper class:
/// <summary>/// Class that helps the creation of control and data templates by using delegates./// </summary>public static class TemplateGenerator{ private sealed class _TemplateGeneratorControl: ContentControl { internal static readonly DependencyProperty FactoryProperty = DependencyProperty.Register("Factory", typeof(Func<object>), typeof(_TemplateGeneratorControl), new PropertyMetadata(null, _FactoryChanged)); private static void _FactoryChanged(DependencyObject instance, DependencyPropertyChangedEventArgs args) { var control = (_TemplateGeneratorControl)instance; var factory = (Func<object>)args.NewValue; control.Content = factory(); } } /// <summary> /// Creates a data-template that uses the given delegate to create new instances. /// </summary> public static DataTemplate CreateDataTemplate(Func<object> 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; } /// <summary> /// Creates a control-template that uses the given delegate to create new instances. /// </summary> public static ControlTemplate CreateControlTemplate(Type controlType, Func<object> 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; }}
You can create a data-template like this:
DataTemplate template = TemplateGenerator.CreateDataTemplate ( () => { var result = new TextBox() result.SetBinding(TextBox.TextProperty, "BindingPathHere"); return result; } );
You are free to use any code to create the control as you will do if you were creating the control directly, without any data-template.For more info, see this tip in code project: http://www.codeproject.com/Tips/808808/Create-Data-and-Control-Templates-using-Delegates