2011-12-08 11 views
14

quiero hacer lo siguiente en tiempo de ejecución en código:¿Cómo creo una plantilla de datos con contenido programáticamente?

<DataTemplate x:Key="lightGreenRectangle"> 
     <Rectangle Fill="LightGreen"/> 
    </DataTemplate> 

Hasta ahora tengo:

public DataTemplate GetColouredRectangleInDataTemplate(Color colour) 
{ 
    DataTemplate dataTemplate = new dataTemplate(); 

    return dataTemplate; 
} 

Ayuda? Sé que esta no es la forma más elegante de diseñar un control, pero el componente para el que quiero especificar un color tiene una propiedad llamada "PointTemplate" de tipo DataTemplate.

+1

Si desea aplicar estilo a un control, debe usar un ControlTemplate, Datatemplate para mostrar los datos de una manera específica. Vuelva a sus preguntas, ¿para qué quiere establecer el color? – MBen

+0

¿algo como esto funciona para usted? DataTemplate asd = new DataTemplate(); asd.DataType = typeof (Rectangle); asd.VisualTree.SetValue (Rectangle.FillProperty, Brushes.Green); – peer

Respuesta

24

Si por cualquier razón usted necesita para crear un DataTemplate programación puede hacer:

XAML:

<Grid x:Name="myGrid"> 
    <ContentControl ContentTemplate="{DynamicResource lightGreenRectangle}" /> 
</Grid> 

En algún lugar de su código:

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

continuación, sólo tiene que añadir DataTemplate a ResourceDictionary para que pueda ser utilizado. Por ejemplo, en el código detrás:

public MainWindow() 
    { 
     InitializeComponent(); 
     AddRectangleTemplateToResources(myGrid); 
    } 

Espero que esto ayude!

+0

Lo hizo. Gracias. – Corpsekicker

+0

¿Es esto posible para Silverlight? –

+0

Nevermind, encontrado: http://blogs.msdn.com/b/scmorris/archive/2008/04/14/defining-silverlight-datagrid-columns-at-runtime.aspx –

6

Usando la siguiente clase de ayuda:

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

Puede crear una plantilla de datos de esta manera:

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

Usted es libre de utilizar cualquier código para crear el control a medida que va a hacer si estabas creando el control directamente, sin ninguna plantilla de datos. Para obtener más información, consulte este consejo en el proyecto de código: http://www.codeproject.com/Tips/808808/Create-Data-and-Control-Templates-using-Delegates

Cuestiones relacionadas