WPF:Formato condicional de TreeView del organigrama
Pregunta
La empresa tiene la tradicional estructura organizativa compleja, definiendo la cantidad de niveles utilizando la letra 'n' en lugar de un número real.Intentaré expresar la estructura que intento lograr en fuente monoespaciada:
Alice
,--------|-------,------,------,
Bob Fred Jack Kim Lucy
| |
Charlie Greg
Darren Henry
Eric
Como puede ver, no es simétrico, ya que Jack, Kim y Lucy informan a Alice pero no tienen informes propios.
Usando un TreeView
con un ItemsPanel
que contiene un StackPanel
y Orientation="Horizontal"
es Suficientemente fácil, pero esto puede resultar en una gran TreeView
¡Una vez que algunas personas tienen a otras 20 reportándoles!Puede también uso Triggers
para echar un vistazo a si un TreeViewItem
tiene hijos con Property="TreeViewItem.HasItems"
, pero esto no está en el mismo contexto que el antes mencionado ItemsPanel
. P.ej:Puedo decir que Fred tiene informes, pero no si ellos tienen sus propios informes.
Entonces, ¿puedes formatear condicionalmente? TreeViewItems
ser verticales si no tienen hijos propios?
Solución 2
Terminé usando los consejos del artículo vinculado, que ya había leído pero no pensé que me ayudarían.
La esencia de esto sucede aquí, en un convertidor:
<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 a su vez se consume en un estilo que creé para 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>
Otros consejos
Josh Smith tiene un excelente artículo de CodeProject sobre TreeView.Léelo aquí