Condividi tramite


Strutture ad albero in WPF

Aggiornamento: novembre 2007

In molte tecnologie, gli elementi e i componenti sono organizzati in una struttura ad albero in cui gli sviluppatori modificano direttamente la struttura ad albero per influire sul rendering di un'applicazione. In Windows Presentation Foundation (WPF) vengono utilizzate anche molte metafore della struttura ad albero per definire le relazioni tra gli elementi del programma.

Nel presente argomento sono contenute le seguenti sezioni.

  • Strutture ad albero in WPF
  • Albero logico
  • Struttura ad albero visuale
  • Strutture ad albero, elementi e host di contenuto
  • Attraversamento della struttura ad albero
  • Route per eventi indirizzati come "struttura ad albero"
  • Risorse e strutture ad albero
  • Argomenti correlati

Strutture ad albero in WPF

La struttura ad albero principale in WPF è la struttura ad albero dell'elemento. Se si crea una pagina dell'applicazione in XAML, la struttura ad albero viene creata in base alle relazioni di nidificazione degli elementi nel markup. Se si crea un'applicazione in codice, la struttura ad albero viene creata in base all'assegnazione dei valori alle proprietà che implementano il modello di contenuto di un elemento specificato. In Windows Presentation Foundation (WPF), sono disponibili due modi di elaborazione e concettualizzazione della struttura ad albero dell'elemento: come albero logico e come struttura ad albero visuale. Le distinzioni tra albero logico e struttura ad albero visuale non sono sempre necessariamente importanti, tuttavia possono talvolta causare problemi ad alcuni sottosistemi WPF e influire sulle scelte fatte nel markup o nel codice.

Sebbene l'albero logico o la struttura ad albero visuale non vengano sempre modificati direttamente, la comprensione del modo in cui le strutture ad albero interagiscono consente di capire il funzionamento dell'ereditarietà della proprietà e del routing degli eventi in WPF.

Albero logico

In WPF è possibile aggiungere contenuti agli elementi utilizzando le proprietà. Ad esempio, è possibile aggiungere elementi a un controllo ListBox utilizzando la proprietà Items. In questo modo, gli elementi vengono collocati nell'oggetto ItemCollection del controllo ListBox. Per aggiungere elementi a un oggetto DockPanel è necessario utilizzare la relativa proprietà Children. In questo caso, gli elementi vengono aggiunti all'oggetto UIElementCollection dell'oggetto DockPanel. Per un esempio di codice, vedere Procedura: aggiungere un elemento dinamicamente.

In Extensible Application Markup Language (XAML), quando si posizionano delle voci elenco in un oggetto ListBox oppure controlli o altri elementi in un oggetto DockPanel, è anche possibile utilizzare le proprietà Items e Children, in modo esplicito o implicito, come nell'esempio seguente.

<DockPanel
  Name="ParentElement"
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  >

  <!--implicit: <DockPanel.Children>-->
  <ListBox DockPanel.Dock="Top">
    <!--implicit: <ListBox.Items>-->
    <ListItem>
      <Paragraph>Dog</Paragraph>
    </ListItem>
    <ListItem>
      <Paragraph>Cat</Paragraph>
    </ListItem>
    <ListItem>
      <Paragraph>Fish</Paragraph>
    </ListItem>
    <!--implicit: </ListBox.Items>-->
  </ListBox>
  <Button Height="20" Width="100" DockPanel.Dock="Top">Buy a Pet</Button>

  <!--implicit: </DockPanel.Children>-->
</DockPanel>

Notare che i tag di elementi proprietà non sono necessari in modo esplicito, poiché il lettore XAML deduce gli elementi proprietà quando crea gli oggetti che generano la rappresentazione dell'oggetto di runtime del file eseguibile dell'applicazione. Per ulteriori informazioni sul modo in cui la sintassi XAML esegue il mapping all'albero logico creato e ai tag derivati, vedere Terminologia della sintassi XAML o Cenni preliminari su XAML. Nell'immagine seguente viene fornita una visione concettuale dell'albero logico costruito in fase di esecuzione (nell'immagine è omessa la diramazione del pulsante).

Schema dell'aspetto dell'albero logico generico

Diagramma della struttura ad albero

Scopo dell'albero logico

Grazie all'albero logico, i modelli di contenuto possono scorrere prontamente i possibili elementi figlio e quindi essere estendibili. Inoltre, l'albero logico fornisce un framework per alcune notifiche, ad esempio quando tutti gli elementi dell'albero logico vengono caricati.

Inoltre, i riferimenti di risorsa vengono risolti cercando verso l'alto nell'albero logico gli insiemi Resources relativi all'elemento di richiesta iniziale e successivamente gli elementi padre. L'albero logico viene utilizzato per la ricerca delle risorse, quando sono presenti sia l'albero logico, sia la struttura ad albero visuale. Per ulteriori informazioni sulle risorse, vedere Cenni preliminari sulle risorse.

Override dell'albero logico

Gli autori di controlli avanzati possono eseguire l'override dell'albero logico effettuando la stessa operazione su molte API che definiscono il modo in cui un oggetto generale o il modello di contenuto aggiunge o rimuove elementi all'interno dell'albero logico. Per un esempio relativo all'override dell'albero logico, vedere Procedura: eseguire l'override dell'albero logico.

Ereditarietà del valore della proprietà

L'ereditarietà del valore della proprietà opera tramite una struttura ad albero ibrida. I metadati effettivi che contengono la proprietà Inherits che consente l'ereditarietà della proprietà sono presenti nella classe FrameworkPropertyMetadataa livello di framework WPF. Pertanto, sia l'elemento padre che contiene il valore originale, sia l'elemento figlio che eredita, devono essere FrameworkElement oppure FrameworkContentElement e devono entrambi appartenere a un albero logico. Tuttavia, l'albero logico dell'elemento padre può essere non contiguo rispetto a quello dell'elemento figlio e l'ereditarietà del valore della proprietà può essere conservata mediante un elemento visivo frapposto che non si trova in un albero logico. Affinché l'ereditarietà del valore della proprietà funzioni coerentemente oltre tale limite, la proprietà che eredita deve essere registrata come proprietà associata. La struttura ad albero esatta utilizzata per l'ereditarietà della proprietà non può essere completamente prevista da un metodo di utilità di una classe di supporto, persino in fase di esecuzione. Per ulteriori informazioni, vedere Ereditarietà del valore della proprietà.

Struttura ad albero visuale

In WPF, oltre al concetto di albero logico esiste anche il concetto di struttura ad albero visuale. Nella struttura ad albero visuale viene descritta la struttura degli elementi visivi rappresentati dalla classe base Visual. Quando si scrive un modello per un controllo, si definisce o ridefinisce la struttura ad albero visuale relativa a quel controllo. La struttura ad albero visuale è di interesse anche per gli sviluppatori che desiderano un controllo di livello inferiore sui disegni per ragioni di prestazioni e ottimizzazione. Un'esposizione della struttura ad albero visuale come parte della programmazione di applicazioni WPF convenzionale consiste nel fatto che le route degli eventi di un evento indirizzato percorrono per la maggior parte la struttura ad albero visuale e non l'albero logico. Questa sottigliezza del comportamento dell'evento indirizzato potrebbe non essere immediatamente visibile, a meno che l'utente non sia un autore di controlli. Il routing nella struttura ad albero visuale consente ai controlli che implementano la composizione a livello visivo di gestire eventi o creare metodi di impostazione degli eventi.

Strutture ad albero, elementi e host di contenuto

Gli elementi di contenuto (classi che derivano da ContentElement) non fanno parte della struttura ad albero visuale, non ereditano da Visual e non dispongono di una rappresentazione visiva. Per non essere visualizzato in un'interfaccia utente, un oggetto ContentElement deve essere ospitato in un host di contenuto che è un oggetto Visual e anche un elemento dell'albero logico, generalmente un oggetto FrameworkElement. È possibile partire dal concetto che l'host di contenuto è come un "browser" per il contenuto e sceglie come visualizzare tale contenuto all'interno dell'area dello schermo controllata dall'host. Quando ospitato, il contenuto può partecipare ad alcuni processi della struttura ad albero che normalmente sono associati alla struttura ad albero visuale. Generalmente, la classe host FrameworkElement include il codice di implementazione che aggiunge tutti gli oggetti ContentElement ospitati alla route dell'evento tramite nodi secondari dell'albero logico del contenuto, anche se il contenuto ospitato non fa parte della vera struttura ad albero visuale. Questa operazione è necessaria affinché ContentElement possa originare un evento indirizzato che indirizzi a qualsiasi elemento diverso da sé stesso.

Attraversamento della struttura ad albero

La classe LogicalTreeHelper fornisce i metodi GetChildren, GetParent e FindLogicalNode per l'attraversamento dell'albero logico. Nella maggior parte dei casi, non è necessario attraversare l'albero logico dei controlli esistenti, poiché questi controlli espongono quasi sempre gli elementi figlio logici come una proprietà dell'insieme dedicata che supporta le API dell'insieme, ad esempio Add, un indicizzatore e così via. L'attraversamento della struttura ad albero è principalmente uno scenario utilizzato dagli autori di controlli che scelgono di non derivare da pattern di controllo previsti per questo scopo, ad esempio ItemsControl o Panel in cui le proprietà dell'insieme sono già definite e che intendono fornire il proprio supporto della proprietà dell'insieme.

La struttura ad albero visuale supporta anche una classe di supporto per l'attraversamento della struttura ad albero visuale, VisualTreeHelper. La struttura ad albero visuale non viene esposta in modo appropriato tramite le proprietà specifiche del controllo, pertanto la classe VisualTreeHelper rappresenta il modo migliore per attraversare la struttura ad albero visuale, se necessario per lo scenario di programmazione. Per ulteriori informazioni, vedere Cenni preliminari sul rendering della grafica in Windows Presentation Foundation.

Route per eventi indirizzati come "struttura ad albero"

Come indicato in precedenza, la route di un evento indirizzato percorre verso l'alto o verso il basso una struttura ad albero, a seconda che si tratti di un evento indirizzato di tunneling o di bubbling. Il concetto di route dell'evento non prevede una classe di supporto diretto che potrebbe essere utilizzata per "percorrere" la route dell'evento indipendentemente dalla generazione di un evento che effettivamente esegue l'indirizzamento. È disponibile una classe che rappresenta la route, EventRoute, tuttavia i metodi di tale classe sono generalmente riservati all'utilizzo interno.

Risorse e strutture ad albero

La ricerca delle risorse attraversa fondamentalmente l'albero logico. Gli oggetti che non sono presenti nell'albero logico possono fare riferimento alle risorse, tuttavia la ricerca viene avviata nel punto in cui tale oggetto è connesso all'albero logico. Solo i nodi dell'albero logico possono disporre di una proprietà Resources che contiene un oggetto ResourceDictionary, pertanto l'attraversamento della struttura ad albero visuale alla ricerca di risorse non offre vantaggi.

Tuttavia, la ricerca delle risorse può anche essere estesa oltre l'albero logico diretto. Per il markup dell'applicazione, la ricerca delle risorse può quindi continuare nelle risorse dell'applicazione, nel supporto dei temi e nei valori di sistema. Se i riferimenti di risorsa sono dinamici, i temi stessi possono fare riferimento anche ai valori di sistema esterni all'albero logico del tema. Per ulteriori informazioni sulle risorse e sulla logica di ricerca, vedere Cenni preliminari sulle risorse.

Vedere anche

Concetti

Cenni preliminari sull’input

Cenni preliminari sul rendering della grafica in Windows Presentation Foundation

Cenni preliminari sugli eventi indirizzati

Inizializzazione di elementi oggetto non presenti in una struttura ad albero di un elemento

Architettura WPF