VisualTreeHelper Classe

Definizione

Fornisce metodi di utilità che possono essere usati per attraversare le relazioni tra oggetti (lungo gli assi dell'oggetto figlio o dell'oggetto padre) nell'albero visuale dell'app.

public ref class VisualTreeHelper sealed
/// [Windows.Foundation.Metadata.ContractVersion(Windows.Foundation.UniversalApiContract, 65536)]
/// [Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
/// [Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
class VisualTreeHelper final
[Windows.Foundation.Metadata.ContractVersion(typeof(Windows.Foundation.UniversalApiContract), 65536)]
[Windows.Foundation.Metadata.MarshalingBehavior(Windows.Foundation.Metadata.MarshalingType.Agile)]
[Windows.Foundation.Metadata.Threading(Windows.Foundation.Metadata.ThreadingModel.Both)]
public sealed class VisualTreeHelper
Public NotInheritable Class VisualTreeHelper
Ereditarietà
Object Platform::Object IInspectable VisualTreeHelper
Attributi

Requisiti Windows

Famiglia di dispositivi
Windows 10 (è stato introdotto in 10.0.10240.0)
API contract
Windows.Foundation.UniversalApiContract (è stato introdotto in v1.0)

Esempio

Di seguito è riportato un esempio di funzione di utilità che può copiare un elenco di elementi figlio di un particolare tipo dall'interno di una struttura ad albero visuale. Usa i metodi di attraversamento di base GetChildrenCount e GetChild. Usa la ricorsione in modo che gli elementi possano essere trovati indipendentemente dal livello di annidamento all'interno di contenitori intermedi. Usa inoltre un metodo di estensione IsSubclassOf di System.Reflection che estende il confronto dei tipi per considerare i sottotipi come corrispondenza per un tipo.

internal static void FindChildren<T>(List<T> results, DependencyObject startNode)
  where T : DependencyObject
{
    int count = VisualTreeHelper.GetChildrenCount(startNode);
    for (int i = 0; i < count; i++)
    {
        DependencyObject current = VisualTreeHelper.GetChild(startNode, i);
        if ((current.GetType()).Equals(typeof(T)) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
        {
            T asType = (T)current;
            results.Add(asType);
        }
        FindChildren<T>(results, current);
    }
}

Commenti

Struttura ad albero visuale

Lo scopo della classe VisualTreeHelper è semplificare l'individuazione degli oggetti che si sta cercando nell'albero di runtime degli oggetti, ma non è disponibile un'API di relazione tra oggetti più diretta per lo scenario. In alcuni casi, non si conoscerà il tipo esatto o il nome dell'oggetto. O forse si sa che un oggetto specifico viene visualizzato da qualche parte nell'albero, ma non si conosce la posizione esatta. Per questi tipi di scenari, VisualTreeHelper è utile perché è possibile trovare in modo ricorsivo tutti gli oggetti nella struttura ad albero visuale e quindi esaminare questo set e cercare una corrispondenza in base ai criteri.

La struttura ad albero visuale per un'app può essere concettualizzata come rappresentazione filtrata dell'albero di oggetti più grande di oggetti e proprietà di un'app. Solo gli oggetti che hanno un'implicazione per il rendering sono presenti in una struttura ad albero visuale. Ad esempio, una classe di raccolta non fa parte della struttura ad albero visuale. La struttura ad albero visuale astrae invece qualsiasi raccolta in un concetto "children".

Tuttavia, la struttura ad albero visuale può includere anche oggetti non rappresentati come elementi XAML nel markup XAML di una pagina. Ciò è dovuto al fatto che la struttura ad albero visuale aggiunge oggetti che sono le parti composite dei controlli. Queste parti di controllo possono provenire da un modello di controllo applicato, che in genere è XAML da un elemento del dizionario risorse o da un relatore.

Il markup XAML e una struttura ad albero visuale non corrispondono esattamente a node-for-node perché XAML è progettato per il markup e facilità d'uso durante la definizione di markup, quindi a volte ha elementi aggiuntivi. Xaml, ad esempio, include elementi di proprietà, che impostano i valori delle proprietà se un elemento viene trovato annidato all'interno di un altro. In una struttura ad albero visuale l'aspetto è simile a una proprietà di un oggetto impostato da un altro oggetto. XAML ha anche un concetto di proprietà di contenuto, in cui la proprietà impostata non è designata in modo esplicito nel markup. Per altre info sulla terminologia specifica e sulle regole per XAML, vedi Panoramica di XAML.

La struttura ad albero visuale viene usata internamente per il processo di rendering dell'interfaccia utente, ma conoscere la struttura della struttura ad albero visuale è importante per determinati scenari, ad esempio la scrittura o la sostituzione di un modello di controllo o l'analisi della struttura e delle parti di un controllo in fase di esecuzione. Per questi scenari, il Windows Runtime fornisce l'API VisualTreeHelper che può esaminare la struttura ad albero visuale in modo più generalizzato. In teoria, è possibile costruire un albero di questo tipo usando anche proprietà padre e figlio specifiche dell'oggetto, ma è necessario conoscere esattamente le proprietà supportate da ogni elemento ed è difficile da individuare o gestire.

In genere si combinano diverse chiamate API di VisualTreeHelper per scrivere funzioni helper personalizzate che esaminano la struttura ad albero visuale in modi specifici per gli scenari dell'app.

Attraversamento di una struttura ad albero visuale

Attraversare l'albero degli oggetti (talvolta noto colloquialmente come camminare l'albero) è una tecnica comune nei modelli a oggetti. Si usano proprietà che fanno riferimento a oggetti figlio ( in genere raccolte) o relazioni padre a un oggetto contenitore (in genere questa operazione viene eseguita dall'interno di una raccolta e restituisce la raccolta stessa). Come descrizione approssimativa del processo, si chiama una successione di proprietà figlio e proprietà padre, o ad esempio metodi helper, per esplorare gli assi dell'albero di oggetti fino a recuperare un valore che contiene l'oggetto che si stava cercando. Come regola generale, dovresti essere in grado di costruire il contenuto in XAML in modo che non sia necessario eseguire una query estesa sulla struttura dell'albero. Per evitare la necessità di attraversare l'albero, devi assegnare agli elementi XAML un valore per l'attributo x:Name / Name nel markup XAML che li crea. In questo modo viene creato un riferimento immediato disponibile per l'accesso al codice in fase di esecuzione ed è una tecnica molto meno soggetta a errori per ottenere riferimenti agli oggetti rispetto all'esplorazione dell'albero. In alternativa, se si creano oggetti tramite codice anziché XAML, è necessario dichiarare campi privati o variabili che mantengono il riferimento all'oggetto in fase di esecuzione. In genere non è necessario attraversare l'albero per trovare gli oggetti creati nel codice.

Tuttavia, esistono casi in cui non è possibile o pratico assegnare un nome a un oggetto e mantenere un riferimento a un oggetto nell'ambito. Uno di questi scenari è l'aggiunta di contenuto dinamico fornito dall'utente o fornito dal data binding oppure se si usano modelli di visualizzazione e oggetti business. In questi casi non è sempre possibile prevedere il numero di elementi aggiunti o la struttura di un controllo e dei relativi elementi figlio. Un altro scenario consiste nell'esaminare un modello applicato per un controllo o una sezione composita di un controllo o contenuto del relatore.

È possibile attraversare l'albero verso il basso (lontano dalla radice) più livelli usando GetChildrenCount per i valori diversi da zero e quindi GetChild per richiedere un indice specifico. Potrebbe essere necessario usare tecniche try/catch o l'equivalente se si tenta di eseguire il cast di elementi come sottotipi UIElement specifici. In genere l'API VisualTreeHelper restituisce elementi come DependencyObject ed è necessario eseguirne il cast per eseguire qualsiasi operazione utile (anche per un'operazione semplice come il controllo del relativo valore Name ).

Note per le versioni precedenti

Windows 8

Threading dell'interfaccia utente

Windows 8 consentite chiamate di funzione VisualTreeHelper che fanno riferimento a oggetti nel thread dell'interfaccia utente errato (non quello corrente). A partire da Windows 8.1, la funzione genera un'eccezione se non viene chiamata dal thread dell'interfaccia utente corrente. Tenere conto di questo nuovo comportamento dovrebbe essere uno scenario di migrazione di app molto insolito; è difficile ottenere elementi dell'interfaccia utente tra thread al primo posto.

Le app compilate per Windows 8 ma in esecuzione in Windows 8.1 usano il comportamento Windows 8.1 e generano in modo specifico la chiamata di funzione VisualTreeHelper anziché in qualsiasi codice dell'app downstream che usa un oggetto tra thread.

Interfaccia utente dell'app per tastiera su schermo

Windows 8 aveva una logica implementata internamente che associava ScrollViewer all'interfaccia utente complessiva dell'app ogni volta che l'utente richiama la tastiera su schermo. Questa tastiera su schermo è una funzionalità di accessibilità specifica che gli utenti richiedono tramite il Centro accessibilità. Non è uguale alla tastiera morbida che può essere visualizzata nell'interfaccia utente dell'app per i controlli di input di testo, se il sistema non rileva alcun dispositivo da tastiera. Ciò che fa ScrollViewer interno è per consentire lo scorrimento dell'area in cui si trova l'app, se lo scorrimento è forzato perché la tastiera occupa spazio dell'interfaccia utente.

A partire da Windows 8.1, il sistema ha ancora un comportamento di interfaccia utente/layout quando viene visualizzata la tastiera su schermo, ma non usa più questo ScrollViewer creato internamente. Usa invece un controllo interno dedicato che il codice dell'app non può modificare o controllare.

La maggior parte degli aspetti di questa modifica del comportamento non influisce affatto sulle app. Tuttavia, l'app potrebbe aver previsto questo comportamento, fornendo uno stile implicito per ScrollViewer destinato a modificare il layout o spostando l'albero con VisualTreeHelper per trovare il controllo ScrollViewer creato internamente e modificarlo in fase di esecuzione. Per un'app compilata per Windows 8.1 tale codice non sarà utile.

Le app create per Windows 8 che vengono eseguite in Windows 8.1 continuano a usare il comportamento di Windows 8.

Cronologia delle versioni

Versione di Windows Versione dell'SDK Valore aggiunto
1903 18362 GetOpenPopupsForXamlRoot

Metodi

DisconnectChildrenRecursive(UIElement)

Rimuove in modo esplicito tutti i riferimenti da un UIElement di destinazione, con l'obiettivo di pulire i cicli di riferimento.

FindElementsInHostCoordinates(Point, UIElement)

Recupera un set di oggetti che si trovano all'interno di un punto di coordinate x-y specificato di un'interfaccia utente dell'app. Il set di oggetti rappresenta i componenti di una struttura ad albero visuale che condivide tale punto.

FindElementsInHostCoordinates(Point, UIElement, Boolean)

Recupera un set di oggetti che si trovano all'interno di un punto di coordinate x-y specificato di un'interfaccia utente dell'app. Il set di oggetti rappresenta i componenti di una struttura ad albero visuale che condivide tale punto.

FindElementsInHostCoordinates(Rect, UIElement)

Recupera un set di oggetti che si trovano all'interno di un frame Rect specificato di un'interfaccia utente dell'app. Il set di oggetti rappresenta i componenti di una struttura ad albero visuale che condividono un'area rettangolare e possono includere elementi che si sovrascludono.

FindElementsInHostCoordinates(Rect, UIElement, Boolean)

Recupera un set di oggetti che si trovano all'interno di un frame Rect specificato di un'interfaccia utente dell'app. Il set di oggetti rappresenta i componenti di una struttura ad albero visuale che condividono un'area rettangolare e possono includere elementi che si sovrascludono.

GetChild(DependencyObject, Int32)

Usando l'indice fornito, ottiene un oggetto figlio specifico dell'oggetto fornito esaminando la struttura ad albero visuale.

GetChildrenCount(DependencyObject)

Restituisce il numero di elementi figlio presenti nell'insieme figlio di un oggetto nella struttura ad albero visuale.

GetOpenPopups(Window)

Recupera una raccolta di tutti i controlli popup aperti dalla finestra di destinazione.

GetOpenPopupsForXamlRoot(XamlRoot)

Recupera una raccolta di tutti i controlli popup aperti da XamlRoot di destinazione.

GetParent(DependencyObject)

Restituisce l'oggetto padre di un oggetto nella struttura ad albero visuale.

Si applica a

Vedi anche