質問

Kind of an odd problem I have here.

I have a pretty basic recursive tree structure:

public class TreeNode
{
    public string Name { get; set; }
    public IEnumerable<TreeNode> Children { get; set; }
}

and am displaying the data in a TreeView using a HierarchicalDataTemplate, like so:

<TreeView Name="_tree">
    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal" >
                <CheckBox/>
                <TextBlock Text="{Binding Path=Name}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

I populate the tree from code behind:

//allTreeNodes is a list of all existing Tree objects
public void PopulateTree(List<TreeNode> allTreeNodes)
{
    foreach (var node in allTreeNodes)
    {
        _tree.Items.Add(node);
    }
}

The result is a TreeView with each existing Tree object as a root node with their respective subtrees.

Note that each TreeNode can be displayed in the tree at multiple locations depending on whether or not it has ancestors.

Up to this point, everything works well, but what I want to do now is only have the checkboxes displayed for the visual root nodes only. I've attempted using a DataTemplateSelector with two HierarchicalDataTemplates, selecting the Template based on an additional boolean property of the TreeNode, but this doesn't work because the TreeNode needs to be displayed with the checkbox once and potentially multiple times without the checkbox.

Any help is appreciated.

Edit: Here is some dummy data to help explain what I want. (Also note that there are no cyclic references in the data.)

+TreeNodeA
  -TreeNodeB
  -TreeNodeC
    -TreeNodeB
+TreeNodeB
+TreeNodeC
  -TreeNodeB
+TreeNodeD
  -TreeNodeE
    -TreeNodeC
      -TreeNodeB
+TreeNodeE
  -TreeNodeC
    -TreeNodeB

In the above view, only the nodes preceded with + should have checkboxes.

役に立ちましたか?

解決

Well, I don't know of any straightforward approaches, but what you could do is to create an Attached Property and apply it to each TreeViewItem element. See more about implementing Attached Properties in the Overview and this example on StackOverflow.

This Attached Property would apply a different style to the TreeViewItem depending on the level.

It would be a bit tricky to get the level unless you're programmatically producing the TreeViewItem hierarchy.

If not, you could either calculate it every time a registration of the Attached Property call is made by traversing up the Visual Tree.

Or you could try - should work in theory - by doing RelativeSource binding to an Attached Property of the parent and increment it by 1 using an IValueConverter:

<TreeViewItem TreeViewLevelStyle.Level="{Binding RelativeSource=
         {RelativeSource Mode=FindAncestor, AncestorType={x:Type TreeViewItem}},
         Converter=IncrementByOneValueConverter}">

(Disclaimer - this is an idea, and not something I tried previously)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top