tags:

views:

38

answers:

1

Apologies for the long post -- Read a few threads about this, but still find it hard to implement. Basically, I have a collection of objects, defined as:

public class LibData
{
    public string Name { get; set; }
    ObservableCollection<LibObject> _list;
    public ObservableCollection<LibObject> List { get { return _list; } }

    public LibData(string name, LibDataType type)
    {
        this.Name = name;
        _list = new ObservableCollection<LibObject>();
    }
}

and the object:

public class LibObject
{
    public string Name { get; set; }

    public LibObject(string name)
    {
        this.Name = name;
    }
}

My main problem is in the XAML, and styling this TreeView. I need to have a specific style for a "root" item, and a specific style for a "leaf". Thing is, that one item in the bound list is "Root->Leaf", and another is "Root->Child->Leaf". I tried this:

<TreeView x:Name="myTree" ItemsSource="{x:Static local:myDataList}">
     <TreeView.ItemTemplate>
         <HierarchicalDataTemplate ItemsSource="{Binding Path=List}" >
             <Grid>
                 <StackPanel Orientation="Horizontal">
                      <TextBlock Text="{Binding Path=Name}" />
                      <CheckBox IsChecked="True" Content="HeaderCheckbox"/>
                 </StackPanel>
             </Grid>
         <HierarchicalDataTemplate.ItemTemplate >
              <DataTemplate>
                  <Grid>
            <StackPanel Orientation="Horizontal">
                <CheckBox IsChecked="True" Content="LeafCheckbox" />
                <TextBlock Text="{Binding Path=Name}"/>
            </StackPanel>
                  </Grid>
              </DataTemplate>
          </HierarchicalDataTemplate.ItemTemplate>
      </HierarchicalDataTemplate>
  </TreeView.ItemTemplate>

This obviously works fine for the "Root->Leaf" item, but not for the "Root-Child-Leaf". The XAML implementation seems to be more of a "hard coded" solution, where I know that the item layout is always "Root->Leaf" - how do I make this dynamic? Again, I have seen solutions to different levels (including using converters), but the problem i'm having is that I need specific styles to root and leaf and nothing for levels in between. I'm wondering if I'm looking at this completely wrong ...

A: 

Easy way to do this. Pull the DataTemplates out of the TreeView and put them in the resources section. Specify the DataType property for each DataTemplate, but do not include a key. The ItemTemplateSelector (a property of type DataTemplateSelector) on the TreeView will do the magic of using whichever DataTemplate suits the correct item type.

Create a HierarchicalDataTemplate for types Root and Child, and a DataTemplate for type Leaf.

Something like this:

<Window.Resources>
    <ResourceDictionary>

        <DataTemplate DataType="{x:Type local:Leaf}">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <CheckBox IsChecked="True" Content="LeafCheckbox" />
                    <TextBlock Text="{Binding Path=SomeValue}"/>
                </StackPanel>
            </Grid>
        </DataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type local:Child}"
                                  ItemsSource="{Binding Children}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="Child " />
                <TextBlock Text="{Binding Path=SomeValue}" />
            </StackPanel>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="{x:Type local:Root}"
                                  ItemsSource="{Binding Children}">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="Root " />
                    <TextBlock Text="{Binding Path=SomeValue}" />
                </StackPanel>
            </Grid>
        </HierarchicalDataTemplate>

    </ResourceDictionary>
</Window.Resources>

<Grid>
    <TreeView x:Name="myTree" ItemsSource="{Binding}" />
</Grid>
mbursill
Is the part of taking the templates out of the treeview resources critical? I didn't mention this, but i'm using this inside a wizard, and each "window" is actually a PageFunction<T> - as I understood, there is no Resources for that.
Yes, it is necessary to take the DataTemplates out of the TreeView. You'd want to do that because you do not want to specify the ItemTemplate directly since in this case the templates should change based on item type. In my rushed example I put the DataTemplates in the Window.Resources, but that could just as easily been the TreeView.Resources.
mbursill
Oh I get it - so putting it in a <TreeView.Resources> clause will do. Cool. I'll give it a try. Thanks.
Changed my data structure and used your approach - worked perfectly