views:

28

answers:

1

Hi,

I have a TreeView whose contents (nested TreeViewItems) are generated from a dataset via databinding, which all seems to work fine. The issue I'm running into is that when I try and manipulate the contents of the TreeViewItem headers in code, the Header property returns the DataRowView that the TreeViewItem was generated from and not, as I was expecting, the control generated by the template.

Here's an example of the template I'm using to generate the TreeViewItems:

    <DataTemplate x:Key="seasonTreeViewItemTemplate">
        <TreeViewItem>
            <TreeViewItem.Header>
                <CheckBox Content="{Binding Path=Row.SeasonID}" Tag="{Binding}" ToolTip="{Binding Path=Row.Title}" IsEnabled="{StaticResource seasonPermitted}" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked" />
            </TreeViewItem.Header>

            <TreeViewItem Header="Championships" ItemTemplate="{StaticResource championshipTreeViewItemTemplate}">
                <TreeViewItem.ItemsSource>
                    <Binding Path="Row" ConverterParameter="FK_Championship_Season">
                        <Binding.Converter>
                            <local:RowChildrenConverter />
                        </Binding.Converter>
                    </Binding>
                </TreeViewItem.ItemsSource>
            </TreeViewItem>
        </TreeViewItem>
    </DataTemplate>

Can anyone point out where I'm going wrong and advise me how to access the header checkboxes (ideally without delving into the VisualTree if possible)?

Thanks, James

A: 

Well, after some searching I have found an adequate solution to the problem.

Using the following code, you can find named items in the template:

if (treeViewItem != null)
{
        //Get the header content presenter.
        ContentPresenter header = treeViewItem.Template.FindName("PART_Header", treeViewItem) as ContentPresenter;

        if (header != null)
        {
            //Find a CheckBox called "checkBoxName"
            CheckBox cb = treeViewItem.HeaderTemplate.FindName("checkBoxName", header) as CheckBox;
        }
} 

Also, for the benefit of anyone else who may not be too clued up on databinding treeviews: The template I posted in my question is not the right way to go about binding a treeview. Use a HierarchicalDataTemplate for each level of the tree. The direct content of the HierarchicalDataTemplate will specify the header content of each subtree and setting the ItemsSource and ItemTemplate properties will allow you to bind and format the subtrees children, for example:

<HierarchicalDataTemplate x:Key="templateName" ItemsSource="{Binding Path=someCollection}" ItemTemplate="{StaticResource someOtherTemplate}">
    <TextBlock Text="{Binding Path=SomeProperty}" />
</HierarchicalDataTemplate>

I hope someone else will find this information useful.

Moonshield