2011-12-08 7 views
14

voglio fare quanto segue in fase di esecuzione in codice:Come si crea un datatemplate con contenuto a livello di programmazione?

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

Finora ho:

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

    return dataTemplate; 
} 

Aiuto? So che questo non è il modo più elegante per disegnare un controllo, ma il componente per cui voglio specificare un colore ha una proprietà chiamata "PointTemplate" di tipo DataTemplate.

+1

Se si desidera impostare un controllo di stile, è necessario utilizzare un oggetto ControlTemplate, Datatemplate consente di visualizzare i dati in un modo specifico. Torna alle tue domande, per cosa vuoi impostare il colore? – MBen

+0

fa qualcosa di simile a questo lavoro per te? DataTemplate asd = new DataTemplate(); asd.DataType = typeof (Rectangle); asd.VisualTree.SetValue (Rectangle.FillProperty, Brushes.Green); – peer

risposta

24

Se per qualsiasi motivo è necessario creare un DataTemplate programmazione si dovrebbe fare:

XAML:

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

Da qualche parte nel codice:

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

Poi basta aggiungere il DataTemplate a un ResourceDictionary in modo che possa essere utilizzato. Ad esempio, nel codice sottostante:

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

Spero che questo aiuti!

+0

Lo ha fatto. Grazie. – Corpsekicker

+0

E 'possibile per Silverlight? –

+0

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

6

Utilizzando la seguente classe di supporto:

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

È possibile creare un data-template in questo modo:

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

Siete liberi di utilizzare qualsiasi codice per creare il controllo come si farà, se stavi creando il controllo direttamente, senza alcun modello di dati. Per ulteriori informazioni, vedere questo progetto di suggerimento nel codice: http://www.codeproject.com/Tips/808808/Create-Data-and-Control-Templates-using-Delegates

Problemi correlati