Come ottenere il pannello all'interno di una vista ad albero (WPF)
-
03-10-2019 - |
Domanda
Come si può ottenere il pannello che viene utilizzato all'interno di un TreeView
? Ho letto che per impostazione predefinita TreeView
utilizza un VirtualizingStackPanel
per questo. Quando guardo un modello TreeView
, tutto quello che vedo è
Possibili soluzioni:
1) Nell'istanza TreeView ( "TV"), dal codice, procedere come segue:. Tv.ItemsPanel
Il problema è che questo non restituisce un pannello, ma un ItemsPanelTemplate ( "Ottiene o imposta il modello che definisce il pannello che controlla il layout delle voci").
2) Fare un modello TreeView che esplicitamente sostituisce
(sto usando un controllo denominato VirtualTreeView che è derivata da TreeView, come si vede qui sotto):
<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>
[I spogliato fuori tutto il disordine qui per la visibilità ...]
Il problema è: questo immediatamente sostituzioni qualsiasi TreeView la layout meccanismo. In realtà, basta avere uno schermo vuoto, anche quando si ha TreeViewItems che riempiono l'albero. Beh, il motivo che voglio ottenere una sospensione del pannello è di prendere alcuni parte alla MeaureOverride, ma senza entrare in tutto questo, io di certo non vogliono riscrivere il libro di come il layout una vista ad albero. Vale a dire, a fare questo passo # 2 modo sembra invalidare il punto di anche utilizzando un TreeView, in primo luogo.
Scusate se v'è una certa confusione qui, grazie per tutto l'aiuto che potete offrire.
Soluzione
C'è una classe chiamata VisualTreeHelper
che consente di ottenere non esposti i controlli figlio / elementi di un controllo.
Questo è il link al metodo GetChild
in quella classe, che consente di enumerare tutti i bambini, etc:
http://msdn.microsoft .com / it-it / library / system.windows.media.visualtreehelper.getchild.aspx
Altri suggerimenti
Di seguito è un supplemento alla risposta data da David sopra. Questo offre un modo per ottenere tutti i bambini che sono visive UIElement
s tramite un metodo di estensione.
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();