Comment obtenir le panneau dans un TreeView (WPF)
-
03-10-2019 - |
Question
Comment peut-on obtenir le panneau qui est utilisé dans un TreeView
? J'ai lu que par défaut TreeView
utilise un VirtualizingStackPanel
pour cela. Quand je regarde un modèle de TreeView
, tout ce que je vois est
Solutions possibles:
1) Sur l'instance de TreeView ( "TV"), à partir du code, procédez comme suit:. Tv.ItemsPanel
Le problème est, cela ne revient pas un panneau, mais un ItemsPanelTemplate ( « obtient ou définit le modèle qui définit le panneau qui contrôle la mise en page des articles »).
2) Faire un modèle TreeView qui remplace explicitement
(je me sers d'un contrôle nommé VirtualTreeview qui est dérivé de TreeView, comme on le voit ci-dessous):
<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>
[Je dépouillé tout encombrement ici pour une meilleure visibilité ...]
Le problème est: immédiatement overrides tout mécanisme mise en page TreeView. En fait, vous obtenez juste un écran vide, même si vous avez TreeViewItems de remplissage de l'arbre. Eh bien, la raison pour laquelle je veux obtenir une prise du panneau est de prendre certains part à la MeaureOverride, mais sans entrer dans tout cela, je ne veux certainement pas réécrire le livre de la façon de mise en page une vue arborescente. À savoir, ce faisant l'étape 2 voies semble invalider le point de même en utilisant un TreeView en premier lieu.
Désolé s'il y a une certaine confusion ici, merci pour toute aide que vous pouvez offrir.
La solution
Il y a une classe appelée VisualTreeHelper
qui vous permet d'obtenir des contrôles enfants non exposés / éléments d'un contrôle.
Voici un lien vers la méthode GetChild
sur cette classe qui vous permet d'énumérer tous les enfants, etc:
Autres conseils
Ce qui suit est un complément à la réponse donnée par David ci-dessus. Cette offre un moyen d'obtenir tous les enfants visuels qui sont UIElement
s via une méthode d'extension.
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();