How to assign different DataTypes to a static HierarchicalDataTemplate in XAML?

312 views Asked by At

In converting my treeview to use checkboxes, as in the article by Josh Smith, I find my working xaml code to use multiple HierarchicalDataTemplates of exactly the same format, but with different DataTypes.

Is there anyway to define a single static HierarchicalDataTemplate in XAML, but assign different datatypes where the xaml instantiates the objects?

Here are two working HierarchicalDataTemplates. The only diffence is in the DataType:

 XAML
 <HierarchicalDataTemplate 
                DataType="{x:Type r:ReportViewModel}" 
                ItemsSource="{Binding Children}"
                >
                    <StackPanel Orientation="Horizontal">
                        <CheckBox
                                Focusable="False" 
                                IsChecked="{Binding IsChecked}" 
                                 VerticalAlignment="Center"
                         />
                        <ContentPresenter 
                            Content="{Binding Name, Mode=OneTime}" 
                             Margin="2,0"
                         />
                    </StackPanel>
                </HierarchicalDataTemplate>

                <HierarchicalDataTemplate 
                DataType="{x:Type r:NetworkViewModel}" 
                ItemsSource="{Binding Children}"
                >
                    <StackPanel Orientation="Horizontal">
                        <CheckBox
        Focusable="False" 
        IsChecked="{Binding IsChecked}" 
        VerticalAlignment="Center"
        />
                        <ContentPresenter 
        Content="{Binding Name, Mode=OneTime}" 
        Margin="2,0"
        />
                    </StackPanel>

                </HierarchicalDataTemplate>

Thanks for any help.

Addendum: I found a partial answer at How do I reuse a HierarchicalDataTemplate?

Unless someone has a better solution?

1

There are 1 answers

0
toadflakz On BEST ANSWER

Another option would be to implement a base class which has the properties as bound to by the TreeView.

e.g.

public class ReportViewModel : NamedViewModel
{
   ....
}

public class NetworkViewModel : NamedViewModel
{
   ....
}

public class NamedViewModel : INotifyPropertyChanged
{

  public string Name {get;set;}
  public bool IsChecked{get;set;}
  public ObservableCollection<NamedViewModel> Children {get; private set;}

  ...etc....
}

NB: Not showing full INotifyPropertyChanged implementation.

Bind any derived class objects to a TreeView.ItemsSource as a collection of the type of the base class which should mean your HierarchicalDataTemplate for the base class will be picked up by the WPF Type Inference system.

e.g.

<HierarchicalDataTemplate 
            DataType="{x:Type base:NamedViewModel}" 
            ItemsSource="{Binding Children}"
            >
                <StackPanel Orientation="Horizontal">
                    <CheckBox
                            Focusable="False" 
                            IsChecked="{Binding IsChecked}" 
                             VerticalAlignment="Center"
                     />
                    <ContentPresenter 
                        Content="{Binding Name, Mode=OneTime}" 
                         Margin="2,0"
                     />
                </StackPanel>
            </HierarchicalDataTemplate>