WPF:Formatação condicional do organograma TreeView
Pergunta
A empresa possui a tradicional estrutura organizacional complexa, definindo a quantidade de níveis utilizando a letra 'n' em vez de um número real.Vou tentar expressar a estrutura que estou tentando alcançar em fonte monoespaçada:
Alice
,--------|-------,------,------,
Bob Fred Jack Kim Lucy
| |
Charlie Greg
Darren Henry
Eric
Como você pode ver, não é simétrico, já que Jack, Kim e Lucy se reportam a Alice, mas não têm relatórios próprios.
Usando um TreeView
com um ItemsPanel
contendo um StackPanel
e Orientation="Horizontal"
é bastante fácil, mas isso pode resultar em um grande TreeView
uma vez que algumas pessoas tenham outras 20 subordinadas a elas!Você pode também use Triggers
para espiar se um TreeViewItem
tem filhos com Property="TreeViewItem.HasItems"
, mas isso não está no mesmo contexto que o mencionado anteriormente ItemsPanel
. Por exemplo:Posso dizer que Fred tem relatórios, mas não se eles têm seus próprios relatórios.
Então, você pode formatar condicionalmente TreeViewItems
ser Vertical se não tiverem filhos?
Solução 2
Acabei usando dicas do artigo vinculado, que já havia lido, mas achei que não me ajudaria.
A essência disso acontece aqui, em um conversor:
<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
Que por sua vez é consumido em um estilo que criei para o 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>
Outras dicas
Josh Smith tem um excelente artigo do CodeProject sobre TreeView.Leia-o aqui