1
votes

If I set the DataContext of a Window using

public partial class MainWindow : Window
{
    readonly TreeViewViewModel TreeView;
    public MainWindow()
    {
      //...
      this.DataContext = TreeView;
    }       
}

then the following XAML works fine

<TreeView x:Name="radTreeView" Grid.Row="1"
                     Margin = "5,5,5,5"
                     ItemsSource = "{Binding FirstGeneration}"
                     Padding = "5"
                     ScrollViewer.HorizontalScrollBarVisibility = "Visible"
                     ScrollViewer.VerticalScrollBarVisibility = "Visible"
                     IsTextSearchEnabled="True" >
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem" >
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}" >
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}"  />
                <TextBlock VerticalAlignment="Center" Text="{Binding Name}" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

However, I need the DataContext to be a property of a ViewModel so that TreeViewViewModel TreeView is a property of MainViewModel mainViewModel and the DataContext set in codebehind as

public partial class MainWindow : Window
{
    private MainViewModel mainViewModel;
    public MainWindow()
    {
      //...
      this.DataContext = this;
    }       
}

I can get parts of the binding working using DataContext = "{Binding MainViewModel.TreeView}" but this only works on the main TreeView element and not the Style, Setter, HierarchicalDataTemplate which don't have a DataContext property.

How do I correctly set the data context for all of the XAML TreeView elements?

Below is what I have tried so far but only ItemsSource = "{Binding FirstGeneration}" is working with the correct data context

<TreeView x:Name="radTreeView" Grid.Row="1"
                     Margin = "5,5,5,5"
                     DataContext = "{Binding MainViewModel.TreeView}"
                     ItemsSource = "{Binding FirstGeneration}"
                     Padding = "5"
                     ScrollViewer.HorizontalScrollBarVisibility = "Visible"
                     ScrollViewer.VerticalScrollBarVisibility = "Visible"
                     IsTextSearchEnabled="True" >
    <TreeView.ItemContainerStyle>
        <Style TargetType="TreeViewItem" >
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        </Style>
    </TreeView.ItemContainerStyle>
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}" >
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}"  />
                <TextBlock VerticalAlignment="Center" Text="{Binding Name}" />
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>
1
My code does actually work okay (doh!) - for simplicity in writing this question I removed DataContext from the CheckBox and TextBox which now works fine in code. dkozl's answer helped dugug the problem.user3904868

1 Answers

1
votes

Assuming that DataContext of the container for radTreeView is an instance of MainViewModel you can do

<TreeView ... DataContext="{Binding TreeView}" ItemsSource="{Binding FirstGeneration}">

or without changing DataContext

<TreeView ... ItemsSource="{Binding TreeView.FirstGeneration}">