Cómo obtener el panel dentro de una vista de árbol (WPF)
-
03-10-2019 - |
Pregunta
¿Cómo se puede obtener el panel que se utiliza dentro de un TreeView
? He leído que por defecto usa un TreeView
VirtualizingStackPanel
para esto. Cuando miro a una plantilla TreeView
, todo lo que veo es
Posibles soluciones:
1) en la instancia de árbol ( "TV"), a partir del código, hacer esto:. Tv.ItemsPanel
El problema es que esto no devuelve un panel, sino una ItemsPanelTemplate ( "Obtiene o establece la plantilla que define el panel de controles que la disposición de los elementos").
2) Hacer una plantilla TreeView que explícitamente reemplaza
(estoy usando un control denominado VirtualTreeview que se deriva de TreeView, como se ve a continuación):
<ControlTemplate x:Key="VirtualTreeViewTemplate" TargetType="{x:Type local:VirtualTreeView}">
<Border>
<local:VirtualScrollViewer
Style="{StaticResource VirtualScrollViewer}"
x:Name="PART_VirtualScrollViewer"
CanContentScroll="True">
<!-- instead of: <ItemsPresenter />, use following: -->
<ItemsControl>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel
Name="PART_ItemsStackPanel"
IsItemsHost="True" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</local:VirtualScrollViewer>
</Border>
</ControlTemplate>
[me quitó todo el desorden aquí para obtener la visibilidad ...]
El problema con esto es: esto inmediatamente anula cualquier disposición TreeView mecanismo. En realidad, sólo una pantalla en blanco, incluso cuando se tiene TreeViewItems que llenan el árbol. Bueno, la razón por la que quiero obtener una bodega del panel es tomar algunos participar en el MeaureOverride, pero sin entrar en todo eso, desde luego no quieren volver a escribir el libro de cómo el diseño una vista de árbol. Es decir, hacer esto, el paso # 2 vías parece invalidar el punto de incluso utilizando un TreeView en el primer lugar.
Lo siento si hay alguna confusión aquí, gracias por cualquier ayuda que pueda ofrecer.
Solución
Hay una clase llamada VisualTreeHelper
que le permite obtener no expuestos controles secundarios / elementos de un control.
Aquí hay un enlace con el método GetChild
en esa clase que le permite enumerar todos los niños, etc:
http://msdn.microsoft .com / es-es / library / system.windows.media.visualtreehelper.getchild.aspx
Otros consejos
El siguiente es un complemento a la respuesta dada por David anteriormente. Esto ofrece una manera de obtener todos los niños que son visuales UIElement
s a través de un método de extensión.
public static class WPFXtensions
{
static public IEnumerable<UIElement> GetDescendantUIElements(this UIElement uiElement)
{
int childrenCnt = VisualTreeHelper.GetChildrenCount(uiElement);
for (int i = 0; i < childrenCnt; i++)
{
Visual childVisual = VisualTreeHelper.GetChild(uiElement, i) as Visual;
if(childVisual == null)
continue;
if (childVisual is UIElement)
{
yield return childVisual as UIElement;
// note: by recursively calling within the loop, we walk the tree all the way down for each
// UIElement encountered before moving to the next UIElement sibling.
foreach (UIElement e in GetDescendantUIElements(childVisual as UIElement))
yield return e;
}
}
}
}
// Use this then like this to retrieve an expected child StackPanel
StackPanel sp1 = (StackPanel)this.GetDescendantUIElements()
.First(uiElem => uiElem is StackPanel);
// Get all of this UIElement's descendants (for a diagnostic look);
// In a run where this was a TreeView, 78 UIElements returned
List<UIElement> uiElements = this.GetDescendantUIElements().ToList();