2011-03-29 58 views
13

如何以編程方式將控件添加到數據模板?在代碼後面創建DataTemplate

例如。下面我創建了TextBlock和DataTemplate。

TextBlock text = new TextBlock(); 
DataTemplate template = new DataTemplate(); 

現在我需要將TextBlock添加到DataTemplate。如何實現這一目標?

我知道有代碼addind數據模板的其他方式落後 1.在XAML中創建一個數據模板和加載在後面的代碼 2.創建並添加使用XamlParser

,但我需要做的就像我在例子中展示的那樣。

需要一些幫助。

回答

23

你必須先聲明一個DataTemplate:

DataTemplate template = new DataTemplate { DataType = typeof(< Type of the object the template refers>) }; 

然後聲明一樣的StackPanel佈局面板這樣

FrameworkElementFactory stackPanelFactory = new FrameworkElementFactory(typeof(StackPanel)); 
stackPanelFactory.SetValue(StackPanel.OrientationProperty, Orientation.Vertical); 

最後附加在它的TextBlock片:

FrameworkElementFactory title = new FrameworkElementFactory(typeof(TextBlock)); 
title.SetBinding(TextBlock.TextProperty, new Binding("< name of your binding >")); 
stackPanelFactory.AppendChild(title); 

爲了顯示以這種方式創建的StackPanel,您必須將它附加到VisualT ree:

template.VisualTree = stackPanelFactory; 

希望它有幫助! :)

19

雖然Archedius的方法工作,正式被棄用,取而代之建議以編程方式創建一個模板使用XamlReader類這樣的Load方法從字符串或內存流加載XAML ...

從MSDN採取
public DataTemplate Create(Type type) 
{ 
    StringReader stringReader = new StringReader(
    @"<DataTemplate 
     xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""> 
      <" + type.Name + @" Text=""{Binding " + ShowColumn + @"}""/> 
     </DataTemplate>"); 
    XmlReader xmlReader = XmlReader.Create(stringReader); 
    return XamlReader.Load(xmlReader) as DataTemplate; 
} 

官方路線:從弗雷德裏克Hedblad的帖子在這裏http://msdn.microsoft.com/en-us/library/system.windows.frameworkelementfactory.aspx

代碼示例:Problems with XamlReader generating DataTemplate

+3

在System.Windows.Markup中使用XamlReader而不是System.Xaml – Jason 2016-02-17 21:37:20

3

我知道這是一個變通,但我發表在鱈魚小費e項目(http://www.codeproject.com/Tips/808808/Create-Data-and-Control-Templates-using-Delegates),允許您使用委託創建數據模板。 例如:

TemplateGenerator.CreateDataTemplate(() => new TextBox()); 

這將足以創建,創建一個新的文本框,一個DataTemplate。如果你想有一個綁定過,也可能是這樣寫的:

TemplateGenerator.CreateDataTemplate 
(
() => 
    { 
    var result = new TextBox(); 
    result.SetBinding(TextBox.TextProperty, "PathForTheBinding"); 
    return result; 
    } 
); 

的TemplateGenerator的代碼如下:

/// <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; 
    } 
} 

而且它有CONTROLTEMPLATES的方法了。

相關問題