Condividi tramite


Panoramica dei pannelli XAML personalizzati

Un pannello è un oggetto che fornisce un comportamento di layout per gli elementi figlio che contiene, quando viene eseguito il rendering del sistema di layout XAML (Extensible Application Markup Language) e viene eseguito il rendering dell'interfaccia utente dell'app.

API importanti: Panel, ArrangeOverride, MeasureOverride

È possibile definire pannelli personalizzati per il layout XAML derivando una classe personalizzata dalla classe Panel. È possibile indicare il comportamento del pannello eseguendo l'override dei metodi MeasureOverride e ArrangeOverride e fornendo la logica che determina le dimensioni e dispone gli elementi figlio.

La classe di base Panel

Per definire una classe di pannelli personalizzata, è possibile derivare direttamente dalla classe Panel o da una delle pratiche classi di pannelli che non sono ristrette, ad esempio Grid o StackPanel. È più facile derivare dalla classe Panel perché può essere difficile aggirare la logica di layout esistente di un pannello che ha già un comportamento di layout. Inoltre, un pannello con comportamento potrebbe avere proprietà esistenti che non sono rilevanti per le funzionalità di layout del pannello.

Dal Pannello, il pannello personalizzato eredita queste API:

  • La proprietà Children.
  • Le proprietà Background, ChildrenTransitions e IsItemsHost e gli identificatori delle proprietà di dipendenza. Nessuna di queste proprietà è virtuale, quindi non è in genere necessario eseguirne l'override o sostituirle. In genere non sono necessarie queste proprietà per scenari di pannello personalizzati, nemmeno per la lettura dei valori.
  • I metodi di override del layout MeasureOverride e ArrangeOverride. Questi sono stati originariamente definiti da FrameworkElement. La classe Panel di base non esegue l'override di questi metodi, ma i pannelli pratici come Grid hanno implementazioni di override implementate come codice nativo e vengono eseguite dal sistema. Fornire implementazioni nuove (o aggiuntive) per ArrangeOverride e MeasureOverride è il grosso dello sforzo necessario per definire un pannello personalizzato.
  • Tutte le altre API di FrameworkElement, UIElement and DependencyObject, such as Height, Visibility and così via. In alcuni casi si fa riferimento a valori di queste proprietà negli override del layout, ma non sono virtuali, quindi in genere non ne viene eseguito l'override o la sostituzione.

L'obiettivo di questa sezione è descrivere i concetti di layout XAML, in modo da poter prendere in considerazione tutte le possibilità per il modo in cui un pannello personalizzato può e dovrebbe comportarsi nel layout. Se si preferisce passare direttamente a destra e vedere un esempio di implementazione del pannello personalizzato, osservare un esempio di pannello BoxPanel personalizzato.

La proprietà Children

La proprietà Children è rilevante per un pannello personalizzato perché tutte le classi derivate da Panel usano la proprietà Children come posizione per archiviare gli elementi figlio contenuti in una raccolta. Children viene designata come proprietà del contenuto XAML per la classe Panel e tutte le classi derivate da Panel possono ereditare il comportamento della proprietà del contenuto XAML. Se una proprietà è designata come proprietà del contenuto XAML, ciò significa che il markup XAML può omettere un elemento della proprietà quando si specifica tale proprietà nel markup e i valori vengono impostati come elementi figli del markup immediati (il "contenuto"). Ad esempio, se si deriva una classe denominata CustomPanel da Panel che non definisce alcun nuovo comportamento, è comunque possibile usare questo markup:

<local:CustomPanel>
  <Button Name="button1"/>
  <Button Name="button2"/>
</local:CustomPanel>

Quando un parser XAML legge questo markup, Children è noto come proprietà del contenuto XAML per tutti i tipi derivati da Panel, quindi il parser aggiungerà i due elementi Button al valore UIElementCollection della proprietà Children. La proprietà del contenuto XAML facilita una relazione padre-figlio semplificata nel markup XAML per la definizione dell'interfaccia utente. Per ulteriori informazioni sulle proprietà del contenuto XAML e sul popolamento delle proprietà della raccolta durante l'analisi di XAML, vedere la Guida alla sintassi di XAML.

Il tipo di raccolta che mantiene il valore della proprietà Children è la classe UIElementCollection. UIElementCollection è una raccolta fortemente tipizzata che usa UIElement come tipo di elemento applicato. UIElement è un tipo di base ereditato da centinaia di tipi pratici di elementi dell'interfaccia utente, quindi l'imposizione dei tipi qui è deliberatamente lasca. Ciò non significa che non sarebbe stato possibile avere un oggetto Brush come figlio diretto di un oggetto Panel e in genere significa che solo gli elementi che si prevede siano visibili nell'interfaccia utente e che partecipano al layout saranno trovati come elementi figlio in un oggetto Panel.

In genere, un pannello personalizzato accetta qualsiasi elemento figlio UIElement da una definizione XAML, semplicemente usando le caratteristiche della proprietà Children così come sono. Come scenario avanzato, è possibile supportare un ulteriore controllo dei tipi degli elementi figlio quando si esegue l'iterazione della raccolta negli override del layout.

Oltre a scorrere l'insieme Children negli override, la logica del pannello potrebbe anche essere influenzata da Children.Count. Potrebbe essere presente una logica che alloca lo spazio almeno in parte in base al numero di elementi, anziché alle dimensioni desiderate e alle altre caratteristiche dei singoli elementi.

Override dei metodi di layout

Il modello di base per i metodi di override del layout (MeasureOverride e ArrangeOverride) è che devono scorrere tutti gli elementi figlio e chiamare il metodo di layout specifico di ogni elemento figlio. Il primo ciclo di layout inizia quando il sistema di layout XAML imposta l'oggetto visivo per la finestra radice. Poiché ogni padre richiama il layout sui relativi elementi figlio, viene propagata una chiamata ai metodi di layout di ogni possibile elemento dell'interfaccia utente che dovrebbe far parte di un layout. Nel layout XAML sono presenti due fasi: misura e disposizione.

Dalla classe Panel di base non si ottiene alcun comportamento del metodo di layout predefinito per MeasureOverride e ArrangeOverride Gli elementi in Children non verranno visualizzati automaticamente come parte della struttura ad albero visuale XAML. Spetta all'utente rendere gli elementi noti al processo di layout, richiamando i metodi di layout su ognuno degli elementi presenti in Children tramite un passaggio di layout all'interno delle implementazioni di MeasureOverride e ArrangeOverride.

Non esiste alcun motivo per chiamare le implementazioni di base negli override del layout, a meno che non si disponga della propria ereditarietà. I metodi nativi per il comportamento del layout (se esistenti) vengono eseguiti indipendentemente e la mancata chiamata dell'implementazione di base derivata dagli override non impedirà l'esecuzione del comportamento nativo.

Durante il passaggio della misurazione, la logica di layout esegue una query su ogni elemento figlio per richiedere le dimensioni desiderate invocando il metodo Measure su tale elemento figlio. La chiamata al metodo Measure stabilisce il valore per la proprietà DesiredSize. Il valore restituito da MeasureOverride è la dimensione desiderata per il pannello stesso.

Durante il passaggio di disposizione, le posizioni e le dimensioni degli elementi figlio vengono determinate nello spazio x-y e la composizione del layout viene preparata per il rendering. Il codice deve chiamare Arrange per ogni elemento figlio in Children in modo che il sistema di layout rilevi che l'elemento appartiene al layout. La chiamata ad Arrange è un precursore della composizione e del rendering, che informa il sistema di layout del posizionamento dell'elemento quando la composizione viene inviata per il rendering.

Molte proprietà e valori contribuiscono al funzionamento della logica di layout in fase di esecuzione. Un modo per pensare al processo di layout è che gli elementi senza elementi figlio (in genere l'elemento più annidato nell'interfaccia utente) sono quelli che possono finalizzare prima le misurazioni. Non hanno dipendenze da elementi figlio che influenzano le dimensioni desiderate. Potrebbero avere le proprie dimensioni desiderate e questi sono suggerimenti per le dimensioni fino a quando il layout non viene effettivamente eseguito. Quindi, il passaggio della misura continua a camminare verso l'alto dell'albero visivo fino a quando l'elemento radice ha le sue misurazioni e tutte le misurazioni possono essere finalizzate.

Il layout candidato deve rientrare nella finestra dell'app corrente. In caso contrario, le parti dell'interfaccia utente verranno ritagliate. I pannelli sono spesso il luogo in cui viene determinata la logica di ritaglio. La logica del pannello può determinare le dimensioni disponibili dall'interno dell'implementazione di MeasureOverride e potrebbe dover spingere le restrizioni relative alle dimensioni agli elementi figlio e dividere lo spazio tra gli elementi figlio in modo che tutto si adatti al meglio. Il risultato del layout è idealmente qualcosa che usa diverse proprietà di tutti componenti del layout ma si adatta comunque all'interno della finestra dell'app. Ciò richiede sia una buona implementazione per la logica di layout dei pannelli, sia una progettazione di interfaccia utente attenta nella parte di qualsiasi codice dell'app che compila un'interfaccia utente usando tale pannello. Se la progettazione complessiva dell'interfaccia utente include più elementi figlio di quanti ne possono essere inseriti nell'app, tale interfaccia non avrà un aspetto ottimale.

Una parte importante di ciò che fa funzionare il sistema di layout è che qualsiasi elemento basato su FrameworkElement dispone già alcuni dei propri comportamenti intrinseci quando agisce come figlio in un contenitore. Ad esempio, esistono diverse API di FrameworkElement che influiscono sul comportamento del layout o sono necessarie per rendere il layout funzionante. tra cui:

MeasureOverride

Il metodo MeasureOverride ha un valore restituito utilizzato dal sistema di layout come DesiredSize iniziale per il pannello stesso quando il metodo Measure viene chiamato nel pannello dal relativo elemento padre nel layout. Le scelte logiche all'interno del metodo sono tanto importanti quanto le operazioni restituite e la logica spesso influenza il valore restituito.

Tutte le implementazioni di MeasureOverride devono scorrere tutti gli elementi Children e chiamare il metodo Measure per ognuno di tali elementi. La chiamata al metodo Measure stabilisce il valore per la proprietà DesiredSize. Ciò potrebbe indicare la quantità di spazio necessaria per il pannello stesso, nonché il modo in cui lo spazio viene diviso tra gli elementi o le dimensioni per un particolare elemento figlio.

Ecco una versione estremamente semplificata di un metodo MeasureOverride:

protected override Size MeasureOverride(Size availableSize)
{
    Size returnSize; //TODO might return availableSize, might do something else
     
    //loop through each Child, call Measure on each
    foreach (UIElement child in Children)
    {
        child.Measure(new Size()); // TODO determine how much space the panel allots for this child, that's what you pass to Measure
        Size childDesiredSize = child.DesiredSize; //TODO determine how the returned Size is influenced by each child's DesiredSize
        //TODO, logic if passed-in Size and net DesiredSize are different, does that matter?
    }
    return returnSize;
}

Gli elementi hanno spesso una dimensione naturale quando sono pronti per il layout. Dopo il passaggio della misura, DesiredSize potrebbe indicare tali dimensioni naturali se il valore availableSize passato per Measure era inferiore. Se la dimensione naturale è maggiore di availableSize passata per Measure, DesiredSize è vincolata a availableSize. Questo è il comportamento dell'implementazione interna di Measure e gli override del layout devono tenere conto di tale comportamento.

Alcuni elementi non hanno una dimensione naturale perché hanno valori Auto per Height e Width. Questi elementi usano la proprietà availableSize completa, perché questo è ciò che rappresenta un valore Auto: ridimensionare l'elemento alla dimensione massima disponibile, che l'elemento padre del layout immediato comunica chiamando Measure con availableSize. In pratica, c'è sempre una misura in base alla quale viene ridimensionata un'interfaccia utente (anche se si tratta della finestra di primo livello). Alla fine, il passaggio della misura risolve tutti i valori Auto in vincoli padre e tutti gli elementi con valore Auto ottengono misurazioni reali (che è possibile ottenere controllando ActualWidth e ActualHeight, al termine del layout).

È legale passare una dimensione a Measure con almeno una dimensione infinita, per indicare che il pannello può tentare di ridimensionarsi per adattarsi alle misurazioni del relativo contenuto. Ogni elemento figlio misurato imposta il valore DesiredSize usando le sue dimensioni naturali. Quindi, durante il passaggio di disposizione, il pannello esegue in genere la disposizione usando tale dimensione.

Gli elementi di testo, come ad esempio TextBlock, hanno un valore ActualWidth e ActualHeight calcolato in base alle relative proprietà di testo e stringa di testo, anche se non è impostato alcun valore Height o Width, e queste dimensioni devono essere rispettate dalla logica del pannello. Il testo ritagliato è un'esperienza dell'interfaccia utente particolarmente negativa.

Anche se l'implementazione non usa le misure di dimensione desiderate, è consigliabile chiamare il metodo Measure per ogni elemento figlio, perché sono presenti comportamenti interni e nativi attivati dalla chiamata di Measure. Affinché un elemento partecipi al layout, Measure deve essere chiamato per ogni elemento figlio passaggio di misurazione, così come il metodo Arrange. La chiamata a questi metodi imposta flag interni sull'oggetto e popola i valori (ad esempio la proprietà DesiredSize) necessari per la logica di layout del sistema quando compila l'albero visivo ed esegue il rendering dell'interfaccia utente.

Il valore restituito da MeasureOverride si basa sulla logica del pannello che interpreta il valore desiredSize o su altre considerazioni sulle dimensioni per ognuno degli elementi figlio in Children quando viene chiamato Measure. Cosa fare con i valori DesiredSize degli elementi figlio e il modo in cui il valore restituito da MeasureOverride deve usarli dipende dalla propria interpretazione logica. In genere non si aggiungono i valori senza modifiche, perché l'input di MeasureOverride è spesso una dimensione disponibile fissa suggerita dall'elemento padre del pannello. Se si supera tale dimensione, il pannello stesso potrebbe essere ritagliato. In genere si confrontano le dimensioni totali degli elementi figlio con le dimensioni disponibili del pannello e si apportano modifiche, se necessario.

Consigli e indicazioni

  • Idealmente, un pannello personalizzato deve essere adatto per essere il primo oggetto visivo vero in una composizione dell'interfaccia utente, ad esempio a un livello immediatamente sotto Page, UserControl o un altro elemento che è la radice della pagina XAML. Nelle implementazioni di MeasureOverride è opportuno non restituire regolarmente il valore Size dell'input senza esaminare i valori. Se il valore Size restituito contiene un valore Infinity, è possibile generare eccezioni nella logica di layout di runtime. Un valore Infinity può provenire dalla finestra principale dell'app, che è scorrevole e pertanto non ha un'altezza massima. Altri contenuti scorrevoli potrebbero presentare lo stesso comportamento.
  • Un altro errore comune nelle implementazioni di MeasureOverride consiste nel restituire una nuova Size predefinita (i valori per altezza e larghezza sono 0). È possibile iniziare con tale valore e potrebbe anche essere il valore corretto se il pannello determina che non deve essere eseguito il rendering di nessuno degli elementi figlio. Tuttavia, un valore Size comporta che il pannello non venga ridimensionato correttamente dall'host. Non richiede spazio nell'interfaccia utente e quindi non ottiene spazio e non esegue il rendering. Tutto il codice del pannello potrebbe funzionare correttamente ma se i contenuti sono stati creato con altezza zero, larghezza zero non sarà possibile visualizzare il pannello o i contenuti.
  • All'interno degli override, evitare la tentazione di eseguire il cast di elementi figlio in FrameworkElement e usare le proprietà calcolate come risultato del layout, in particolare ActualWidth e ActualHeight. Per gli scenari più comuni, è possibile basare la logica sul valore DesiredSize dell'elemento figlio e non sono necessarie le proprietà correlate Height o Width di un elemento figlio. Per i casi specializzati, in cui si conosce il tipo di elemento e si hanno informazioni aggiuntive, ad esempio le dimensioni naturali di un file di immagine, è possibile usare le informazioni specializzate dell'elemento perché non è un valore che viene attivamente modificato dai sistemi di layout. L'inclusione di proprietà calcolate dal layout come parte della logica di layout aumenta notevolmente il rischio di definire un ciclo di layout non intenzionale. Questi cicli causano una condizione in cui non è possibile creare un layout valido e il sistema può generare un'eccezione LayoutCycleException se il ciclo non è recuperabile.
  • I pannelli di solito dividono lo spazio disponibile tra più elementi figlio, anche se il modo esatto in cui lo spazio viene diviso varia. Ad esempio, Grid implementa la logica di layout che usa i valori RowDefinition e ColumnDefinition per dividere lo spazio nelle celle Grid, supportando sia il ridimensionamento star che con i valori in pixel. Se si tratta di valori in pixel, le dimensioni disponibili per ogni figlio sono già note, quindi questo è ciò che viene passato come dimensione di input per il metodo Measure per uno stile a griglia.
  • I pannelli stessi possono introdurre dello spazio riservato per la spaziatura interna tra gli elementi. In questo caso, assicurarsi di esporre le misurazioni come proprietà distinta da Margin o da qualsiasi proprietà di Padding .
  • Gli elementi possono avere valori per le proprietà ActualWidth e ActualHeight in base a un passaggio di layout precedente. Se i valori cambiano, il codice dell'interfaccia utente dell'app può inserire i gestori per LayoutUpdated sugli elementi se è presente una logica speciale da eseguire, ma la logica del pannello in genere non deve verificare la presenza di modifiche con la gestione degli eventi. Il sistema di layout sta già determinando quando eseguire di nuovo il layout perché una proprietà rilevante per il layout ha modificato il suo valore e la proprietà MeasureOverride o ArrangeOverride di un pannello vengono chiamate automaticamente nelle circostanze appropriate.

ArrangeOverride

Il metodo ArrangeOverride ha un valore restituito Size utilizzato dal sistema di layout durante il rendering del pannello stesso, quando il metodo Arrange viene chiamato sul pannello dal relativo elemento padre nel layout. È tipico che l'input finalSize e il valore Size restituito da ArrangeOverride siano gli stessi. In caso contrario, significa che il pannello sta tentando di assumere dimensioni diverse rispetto a quelle reclamate dagli altri elementi partecipanti al layout. Le dimensioni finali sono state basate sull'esecuzione precedente del passaggio di misurazione del layout tramite il codice del pannello, quindi la restituzione di una dimensione diversa non è tipica, significa che si sta deliberatamente ignorando la logica della misura.

Non restituire un valore Size con un componente Infinity. Il tentativo di usare tale valore Size genera un'eccezione dal layout interno.

Tutte le implementazioni di ArrangeOverride devono scorrere tutti gli elementi Children e chiamare il metodo Arrange per ognuno di tali elementi. Analogamente a Measure, Arrange non restituisce un valore. A differenza di Measure, nessuna proprietà calcolata viene impostata come risultato (tuttavia, l'elemento in questione genera tipicamente un evento LayoutUpdated).

Ecco uno versione di base molto semplice di un metodo ArrangeOverride:

protected override Size ArrangeOverride(Size finalSize)
{
    //loop through each Child, call Arrange on each
    foreach (UIElement child in Children)
    {
        Point anchorPoint = new Point(); //TODO more logic for topleft corner placement in your panel
       // for this child, and based on finalSize or other internal state of your panel
        child.Arrange(new Rect(anchorPoint, child.DesiredSize)); //OR, set a different Size 
    }
    return finalSize; //OR, return a different Size, but that's rare
}

Il passaggio di disposizione del layout può verificarsi senza essere preceduto da un passaggio di misura. Tuttavia, ciò si verifica solo quando il sistema di layout non ha determinato alcuna proprietà modificata che avrebbe influenzato le misurazioni precedenti. Ad esempio, se un allineamento cambia, non è necessario misurare nuovamente l'elemento specifico perché DesiredSize non cambia quando cambia la scelta di allineamento. D'altra parte, se ActualHeight cambia in qualsiasi elemento di un layout, è necessario un nuovo passaggio di misura. Il sistema di layout rileva automaticamente le modifiche delle misure effettive, richiama di nuovo il passaggio della misura e quindi esegue un altro passaggio di disposizione.

L'input per Arrange accetta un valore Rect. Il modo più comune per costruire questo oggetto Rect consiste nell'usare il costruttore con un input Point e un input Size. Point è il punto in cui deve essere posizionato l'angolo superiore sinistro del rettangolo di selezione per l'elemento. Size rappresenta le dimensioni utilizzate per eseguire il rendering di tale particolare elemento. Spesso si usa DesiredSize per tale elemento come valore Size, perché la definizione del valore DesiredSize per tutti gli elementi coinvolti nel layout era lo scopo del passaggio di misura del layout. Il passaggio di misura determina il ridimensionamento completo degli elementi in modo iterativo, così che il sistema di layout possa ottimizzare la modalità di posizionamento degli elementi al passaggio di disposizione.

Ciò che in genere varia tra le implementazioni di ArrangeOverride è la logica in base alla quale il pannello determina il componente Point di come dispone ogni elemento figlio. Un pannello con posizionamento assoluto, ad esempio Canvas, usa le informazioni di posizionamento esplicite ottenute da ogni elemento tramite i valori Canvas.Left e Canvas.Top. Un pannello con divisione dello spazio, ad esempio Grid, utilizza operazioni matematiche per dividere lo spazio disponibile in celle e ogni cella riceve un valore x-y che indica la posizione e la disposizione del relativo contenuto. Un pannello adattivo, ad esempio StackPanel, può espandersi per adattarsi al contenuto nella dimensione di orientamento.

Ci sono ancora influenze aggiuntive sul posizionamento degli elementi nel layout, oltre a ciò che si controlla direttamente e passa ad Arrange. Queste provengono dall'implementazione nativa interna di Arrange comune a tutti i tipi derivati di FrameworkElement e incrementate da altri tipi, ad esempio elementi di testo. Ad esempio, gli elementi possono avere margine e allineamento e alcuni possono avere spaziatura interna. Queste proprietà spesso interagiscono. Per ulteriori informazioni, vedere Allineamento, margini e spaziatura interna.

Pannelli e controlli

Evitare di inserire funzionalità in un pannello personalizzato che deve essere invece realizzato come controllo personalizzato. Il ruolo di un pannello consiste nel presentare qualsiasi contenuto degli elementi figli presenti all'interno di esso, come funzione del layout che viene eseguito automaticamente. Il pannello può aggiungere decorazioni al contenuto (in modo simile a come un Border aggiunge il bordo intorno all'elemento presentato) o eseguire altre regolazioni correlate al layout, ad esempio la spaziatura interna. Questo è però il massimo che si consiglia di fare quando si estende l'albero visuale oltre le operazioni di reporting e di utilizzo delle informazioni dall'oggetto figlio.

Se è presente un'interazione accessibile all'utente, è consigliabile scrivere un controllo personalizzato, non un pannello. Ad esempio, un pannello non deve aggiungere visualizzazioni di scorrimento al contenuto presentato, anche se l'obiettivo è impedire il ritaglio, perché le barre di scorrimento, i pollici e così via sono parti di controllo interattive. Il contenuto potrebbe presentare barre di scorrimento dopo tutto, ma è consigliabile lasciarle tutto così fino alla logica dell'elemento figlio. Non forzarlo aggiungendo lo scorrimento come operazione di layout. È possibile creare un controllo e scrivere anche un pannello personalizzato che svolge un ruolo importante nella struttura ad albero visuale del controllo, quando si tratta di presentare contenuto in tale controllo. Il controllo e il pannello devono essere oggetti di codice distinti.

Un motivo per cui la distinzione tra controllo e pannello è importante è dovuta a Microsoft UI Automation e all'accessibilità. I pannelli forniscono un comportamento di layout visivo, non un comportamento logico. La modalità di visualizzazione visiva di un elemento dell'interfaccia utente non è un aspetto dell'interfaccia utente che in genere è importante per gli scenari di accessibilità. L'accessibilità riguarda l'esposizione delle parti di un'app che sono logicamente importanti per comprendere un'interfaccia utente. Quando è necessaria l'interazione, i controlli devono esporre le possibilità di interazione all'infrastruttura di automazione dell'interfaccia utente. Per maggiori informazioni, vedi I colleghi dell'automazione personalizzata.

Altre API di layout

Esistono altre API che fanno parte del sistema di layout, ma non sono dichiarate da Panel. È possibile usarli in un'implementazione del pannello o in un controllo personalizzato che usa pannelli.

  • UpdateLayout, InvalidateMeasure e InvalidateArrange sono metodi che avviano un calcolo del layout. InvalidateArrange potrebbe non attivare un passaggio di misura, ma gli altri due sì. Non chiamare mai questi metodi dall'interno di un override del metodo di layout, perché quasi certamente causano un ciclo di layout. neanche il codice di controllo deve chiamarli. La maggior parte degli aspetti del layout viene attivata automaticamente rilevando le modifiche apportate alle proprietà di layout definite dal framework, come ad esempio Width e così via.
  • LayoutUpdated è un evento che viene generato con la modifica di alcuni aspetti del layout dell'elemento. Questo aspetto non è specifico dei pannelli. L'evento è definito da FrameworkElement.
  • SizeChanged è un evento che viene generato solo dopo la finalizzazione dei passaggi di layout e indica che ActualHeight o ActualWidth hanno subito modifiche. Si tratta di un altro evento di FrameworkElement. Ci sono casi in cui LayoutUpdated viene attivato, ma SizeChanged no. Ad esempio, il contenuto interno potrebbe essere riorganizzato, ma le dimensioni dell'elemento non sono cambiate.

Riferimento

Concetti