tags:

views:

1215

answers:

2

The company has the traditional complex organizational structure, defining the amount of levels using the letter 'n' rather than an actual number. I will try and express the structure I'm trying to achieve in mono-spaced font:

         Alice
 ,--------|-------,------,------,
Bob      Fred    Jack   Kim    Lucy
 |        |      
Charlie  Greg    
Darren   Henry
Eric

As you can see it's not symmetrical, as Jack, Kim and Lucy report to Alice but have no reports of their own.

Using a TreeView with an ItemsPanel containing a StackPanel and Orientation="Horizontal" is easy enough, but this can result in a very large TreeView once some people have 20 others reporting to them! You can also use Triggers to peek into whether a TreeViewItem has children with Property="TreeViewItem.HasItems", but this is not in the same context as the before-mentioned ItemsPanel. Eg: I can tell that Fred has reports, but not whether they have reports of their own.

So, can you conditionally format TreeViewItems to be Vertical if they have no children of their own?

+1  A: 

Josh Smith has a excecllent CodeProject article about TreeView. Read it here

rudigrobler
A: 

I did end up using tips from the linked article, which I'd already read through but didn't think would help me.

The meat of it happens here, in a converter:

<ValueConversion(GetType(ItemsPresenter), GetType(Orientation))> _
Public Class ItemsPanelOrientationConverter
Implements IValueConverter

Public Function Convert(ByVal value As Object, ByVal targetType As System.Type, _
ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) _
As Object Implements System.Windows.Data.IValueConverter.Convert

    'The 'value' argument should reference an ItemsPresenter.'
    Dim itemsPresenter As ItemsPresenter = TryCast(value, ItemsPresenter)
    If itemsPresenter Is Nothing Then
        Return Binding.DoNothing
    End If

    'The ItemsPresenter''s templated parent should be a TreeViewItem.'
    Dim item As TreeViewItem = TryCast(itemsPresenter.TemplatedParent, TreeViewItem)
    If item Is Nothing Then
        Return Binding.DoNothing
    End If

    For Each i As Object In item.Items
        Dim element As StaffMember = TryCast(i, StaffMember)
        If element.IsManager Then
            'If this element has children, then return Horizontal'
            Return Orientation.Horizontal
        End If
    Next

    'Must be a stub ItemPresenter'
    Return Orientation.Vertical

End Function

Which in turn gets consumed in a style I created for the TreeView:

    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate >
                <ItemsPanelTemplate.Resources>
                    <local:ItemsPanelOrientationConverter x:Key="conv" />
                </ItemsPanelTemplate.Resources>
                <StackPanel IsItemsHost="True" 
                            Orientation="{Binding   
                            RelativeSource={x:Static RelativeSource.TemplatedParent}, 
                            Converter={StaticResource conv}}" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
Mark Glorie