Willem
Willem

Reputation: 9486

How to create a HierarchicalDataTemplate in code-behind?

I have the need to create a HierarchicalDataTemplate for a TreeView in code-behind.

This is what my XAML looks like:

<DataTemplate x:Key="DetailTemplate">
        <StackPanel Orientation="Horizontal">
            <Image Height="15" Width="15" Source="{Binding Image}" Margin="0,0,5,0"/>
            <TextBlock Text="{Binding Text}" />
        </StackPanel>
    </DataTemplate>

    <HierarchicalDataTemplate x:Key="MasterDetailTemplate" 
                              ItemsSource="{Binding SomeSource}" 
                              ItemTemplate="{StaticResource DetailTemplate}">
        <StackPanel Orientation="Horizontal">
            <Image Height="15" Width="15" Source="{Binding Image}" Margin="0,0,5,0"/>
            <TextBlock Text="{Binding Text}" />
        </StackPanel>
    </HierarchicalDataTemplate>

This is what i got so far in c#:

        Image image = new Image();
        image.Name = "image";
        image.Height = 15;
        image.Width = 15;

        Binding imageBinding = new Binding("Image");
        BindingOperations.SetBinding(image, Image.SourceProperty, imageBinding);

        TextBlock textBlock = new TextBlock();
        textBlock.Name = "textBlock";

        Binding textBinding = new Binding("Text");
        BindingOperations.SetBinding(textBlock, TextBlock.TextProperty, textBinding);

        StackPanel stackPanel = new StackPanel();
        stackPanel.Orientation = Orientation.Horizontal;

        stackPanel.Children.Add(image);
        stackPanel.Children.Add(textBlock);

        DataTemplate dataTemplate = new DataTemplate();
        dataTemplate.DataTemplateKey

I am stuck at the DataTemplateKey.

Upvotes: 2

Views: 4211

Answers (2)

naioleaga
naioleaga

Reputation: 1

I do that using resources in XAML:

<DataTemplate x:Key="TreeItemTemplate" DataType="{x:Type a:DriveStatusVar}">
 <StackPanel Orientation="Horizontal">
 <TextBlock  Text="{Binding PathName, NotifyOnSourceUpdated = True, NotifyOnTargetUpdated=True, Mode=TwoWay}" FontSize="10" Style="{StaticResource textBlockStyle}" IsEnabled="True"/>
 </StackPanel>
</DataTemplate>

<HierarchicalDataTemplate x:Key="TreeModTemplate" DataType="{x:Type a:ModuleGroup}" ItemsSource="{Binding Items}">
<StackPanel Orientation="Horizontal">
<Image  Source="{StaticResource add}"  Width="15" Height="15"></Image>
<TextBlock Text="{Binding Name, NotifyOnSourceUpdated = True, NotifyOnTargetUpdated=True,  Mode=TwoWay}" Style="{StaticResource textBlockStyle}" />
<TextBlock Text=" [" Foreground="Black" />
<TextBlock Text="{Binding Items.Count}" Foreground="Black" />
<TextBlock Text=" Items]" Foreground="Black" />
</StackPanel>
</HierarchicalDataTemplate>

and use them in code behind where define and create theTreeView object:

TreeView tree = new TreeView(); 
HierarchicalDataTemplate hdt = (HierarchicalDataTemplate)this.Resources["TreeModTemplat"];
hdt.ItemTemplate = (DataTemplate)this.Resources["TreeItemTemplate"];                        
tree.ItemTemplate = hdt;
//add itemsource
 tree.ItemsSource = modList;

modList is a list of ModuleGroup class with a list Items. Items is a list of DriveStatusVar class

 internal class ModuleGroup : INotifyPropertyChanged, ICloneable
{
    private bool _isSelected;
    private bool _isExpanded;
    private bool _isEdited;
    private string _name;
    private string _codesysName;
    private int _codesysId;
    private int _bits;
    private int _level;

    public  ObservableCollection<DriveStatusVar> Items { get; set; }

    public ObservableCollection<Alarm> Alarms { get; set; }

    public List<string> States { get; set; }

    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            OnPropertyChanged("IsSelected");
        }
    }

and so on... if anybody need more code, please tell me! this is just a piece of them.

Upvotes: 0

Vinit Sankhe
Vinit Sankhe

Reputation: 19885

OK In my comment to your question I specified the code behind way of specifying templates. Now to use / refer them with a key when we add them into ResourceDictionaties, we must add them with a Key.

   myWindow.Resources.Add("MasterDetailTemplate", dataTemplate);

Instead of myWindow it can be myParentPanel i.e. any ancestor of your tree view.

But there is one issue..

The Key (i.e. the DataTemplate) doesnt exist at design time. You are creating and adding it at runtime.

So if you are referring this datatemplate then

  1. Either refer the resource after it is are added to the resource dictionary.

    e.g.

    myWindow.Resources.Add(
         "MasterDetailTemplate",
         dataTemplate);
    
     myTreeView.ItemTemplate
       = myWindow.Resources["MasterDetailTemplate"] as HierarchicalDataTemplate;
    
  2. Refer the dynamically created data template as DynamicResource in XAML. DynamicResource removes the need of pre-existence of MasterDetailTemplate in any resource dictionary.

    <TreeView ItemTemplate="{DynamicResource MasterDetailTemplate}" ... >
      ....
    </TreeView>
    

Hope this helps.

Upvotes: 4

Related Questions