Condividi tramite


Metadati delle proprietà di dipendenza (WPF .NET)

Il sistema di proprietà Windows Presentation Foundation (WPF) include un sistema di report dei metadati delle proprietà di dipendenza. Le informazioni disponibili tramite il sistema di reporting dei metadati superano ciò che è disponibile tramite reflection o le caratteristiche generali del Common Language Runtime (CLR). Quando si registra una proprietà di dipendenza, è possibile creare e assegnare metadati. Se si deriva da una classe che definisce una proprietà di dipendenza, è possibile eseguire l'override dei metadati per la proprietà di dipendenza ereditata. Inoltre, se si aggiunge la propria classe come proprietario di una proprietà di dipendenza, è possibile eseguire l'override dei metadati della proprietà di dipendenza ereditata.

Prerequisiti

L'articolo presuppone una conoscenza di base delle proprietà di dipendenza e che tu abbia letto la panoramica delle proprietà di dipendenza. Per seguire gli esempi in questo articolo, è utile se si ha familiarità con Extensible Application Markup Language (XAML) e si sa come scrivere applicazioni WPF.

Modalità di utilizzo dei metadati

È possibile eseguire query sui metadati delle proprietà di dipendenza per esaminare le caratteristiche di una proprietà di dipendenza. Quando il sistema di proprietà elabora una proprietà di dipendenza, accede ai relativi metadati. L'oggetto metadati per una proprietà di dipendenza contiene i tipi di informazioni seguenti:

  • Valore predefinito della proprietà di dipendenza, impostato dal sistema di proprietà quando non viene applicato alcun altro valore, ad esempio un valore locale, uno stile o un valore di ereditarietà. Per altre informazioni sulla precedenza del valore durante l'assegnazione in fase di esecuzione dei valori delle proprietà di dipendenza, vedere precedenza del valore della proprietà di dipendenza.

  • Riferimenti ai callback dei valori di coercizione e ai callback di modifica delle proprietà nel tipo di proprietario. È possibile ottenere riferimenti solo ai callback che dispongono di un modificatore di accesso public o che si trovano all'interno dell'ambito di accesso consentito. Per ulteriori informazioni sui callback delle proprietà di dipendenza, consultare callback e convalida delle proprietà di dipendenza.

  • Caratteristiche delle proprietà di dipendenza a livello di framework WPF (se la proprietà di dipendenza è una proprietà del framework WPF). I processi WPF, ad esempio il motore di layout del framework e la logica di ereditarietà delle proprietà, eseguono query sui metadati a livello di framework WPF. Per ulteriori informazioni, consultare i metadati delle proprietà di Framework.

API dei metadati

La classe PropertyMetadata archivia la maggior parte dei metadati usati dal sistema di proprietà. Le istanze di metadati possono essere create e assegnate da:

  • Tipi che effettuano la registrazione delle proprietà di dipendenza nel sistema delle proprietà.

  • Tipi che ereditano da una classe che definisce una proprietà di dipendenza.

  • Tipi che si aggiungono come proprietario di una proprietà di dipendenza.

Se un tipo registra una proprietà di dipendenza senza specificare i metadati, il sistema di proprietà assegna un oggetto PropertyMetadata con valori predefiniti per tale tipo alla proprietà di dipendenza.

Per recuperare i metadati per una proprietà di dipendenza, chiamare uno degli overload GetMetadata nell'identificatore DependencyProperty. I metadati vengono restituiti come oggetto PropertyMetadata.

Esistono classi di metadati più specifiche, derivate da PropertyMetadata, per aree architetturali diverse. Ad esempio, UIPropertyMetadata supporta la creazione di report di animazione e FrameworkPropertyMetadata supporta le proprietà del framework WPF. Le proprietà di dipendenza possono anche essere registrate con le classi derivate PropertyMetadata. Anche se GetMetadata restituisce un oggetto PropertyMetadata, se applicabile è possibile eseguire il cast a un tipo derivato per esaminare le proprietà specifiche del tipo.

Le caratteristiche delle proprietà esposte da FrameworkPropertyMetadata vengono talvolta definite flag . Quando si crea un'istanza di FrameworkPropertyMetadata, è possibile passare un'istanza del tipo di enumerazione FrameworkPropertyMetadataOptions nel costruttore FrameworkPropertyMetadata. FrameworkPropertyMetadataOptions consente di specificare i flag di metadati in combinazione bit per bit. Il FrameworkPropertyMetadata usa FrameworkPropertyMetadataOptions per mantenere ragionevole la lunghezza della firma del costruttore. Nella registrazione delle proprietà di dipendenza, i flag di metadati impostati su FrameworkPropertyMetadataOptions vengono esposti all'interno di FrameworkPropertyMetadata come proprietà Boolean anziché una combinazione bit per bit di flag, per rendere più intuitiva l'esecuzione di query sulle caratteristiche dei metadati.

Sovrascrivere o creare nuovi metadati?

Quando si eredita una proprietà di dipendenza, è possibile modificare le caratteristiche della proprietà di dipendenza eseguendo l'override dei relativi metadati. Tuttavia, potrebbe non essere sempre possibile eseguire lo scenario della proprietà di dipendenza eseguendo l'override dei metadati e talvolta è necessario definire una proprietà di dipendenza personalizzata nella classe con nuovi metadati. Le proprietà di dipendenza personalizzate hanno le stesse funzionalità delle proprietà di dipendenza definite dai tipi WPF. Per altre informazioni, vedere Proprietà di dipendenza personalizzate.

Una caratteristica di una proprietà di dipendenza che non è possibile sovrascrivere è il tipo di valore. Se una proprietà di dipendenza ereditata ha il comportamento approssimativo necessario, ma lo scenario richiede un tipo di valore diverso, è consigliabile implementare una proprietà di dipendenza personalizzata. Potrebbe essere possibile collegare i valori delle proprietà tramite la conversione del tipo o un'altra implementazione nella classe derivata.

Scenari per l'override dei metadati

Gli scenari di esempio per l'override dei metadati delle proprietà di dipendenza esistenti sono:

  • Modifica del valore predefinito, ovvero uno scenario comune.

  • Modificare o aggiungere callback per i cambiamenti delle proprietà, cosa che potrebbe essere necessaria se una proprietà di dipendenza ereditata interagisce con altre proprietà di dipendenza in modo diverso rispetto alla sua implementazione di base. Una delle caratteristiche di un modello di programmazione che supporta codice e markup è che i valori delle proprietà possono essere impostati in qualsiasi ordine. Questo fattore può influire sulla modalità di implementazione dei callback di modifica delle proprietà. Per altre informazioni, vedere richiami delle proprietà di dipendenza e convalida.

  • Modifica delle opzioni dei metadati delle proprietà del framework WPF . In genere, le opzioni dei metadati vengono impostate durante la registrazione di una nuova proprietà di dipendenza, ma è possibile ridefinirle nelle chiamate OverrideMetadata o AddOwner. Per ulteriori informazioni su come sostituire i metadati delle proprietà del framework, vedere Specificare FrameworkPropertyMetadata. Per informazioni su come impostare le opzioni dei metadati delle proprietà del framework durante la registrazione di una proprietà di dipendenza, vedere Proprietà di dipendenza personalizzate.

Nota

Poiché i callback di convalida non fanno parte dei metadati, non possono essere modificati eseguendo l'override dei metadati. Per ulteriori informazioni, vedere i callback per la convalida dei valori .

Sostituzione dei metadati

Quando si implementa una nuova proprietà di dipendenza, è possibile impostarne i metadati usando gli overload del metodo Register. Se la classe eredita una proprietà di dipendenza, è possibile eseguire l'override dei valori dei metadati ereditati usando il metodo OverrideMetadata. Ad esempio, è possibile usare OverrideMetadata per impostare valori specifici del tipo. Per ulteriori informazioni ed esempi di codice, vedere Sovrascrivere i metadati per una proprietà di dipendenza.

Un esempio di proprietà di dipendenza WPF è Focusable. La classe FrameworkElement registra Focusable. La classe Control deriva da FrameworkElement, eredita la proprietà di dipendenza Focusable ed esegue l'override dei metadati della proprietà ereditata. L'override modifica il valore predefinito della proprietà da false a true, ma mantiene altri valori di metadati ereditati.

Poiché la maggior parte delle proprietà di dipendenza esistenti non sono proprietà virtuali, l'implementazione ereditata oscura il membro esistente. Quando si esegue l'override di una caratteristica dei metadati, il nuovo valore di metadati sostituisce il valore originale o viene unito:

  • Per un DefaultValue, il nuovo valore sostituirà il valore predefinito esistente. Se non si specifica un DefaultValue nei metadati di override, il valore proviene dall'antenato più vicino che ha specificato DefaultValue nei metadati.

  • Per un PropertyChangedCallback, la logica di unione predefinita archivia tutti i valori PropertyChangedCallback in una tabella e tutti vengono richiamati in una modifica della proprietà. L'ordine di callback è determinato dalla profondità della classe, per cui un callback registrato dalla classe di base nella gerarchia viene eseguito per primo.

  • Per un CoerceValueCallback, il nuovo valore sostituirà il valore CoerceValueCallback esistente. Se non si specifica un CoerceValueCallback nei metadati di sostituzione, il valore deriva dall'antenato più vicino che ha specificato CoerceValueCallback nei metadati.

Nota

La logica di unione predefinita viene implementata dal metodo Merge. È possibile specificare la logica di unione personalizzata in una classe derivata che eredita una proprietà di dipendenza eseguendo l'override di Merge in tale classe.

Aggiungere una classe come proprietario

Per "ereditare" una proprietà di dipendenza registrata in una gerarchia di classi diversa, usare il metodo AddOwner. Questo metodo viene in genere usato quando la classe di aggiunta non è derivata dal tipo che ha registrato la proprietà di dipendenza. Nella chiamata AddOwner, la classe di aggiunta può creare e assegnare metadati specifici del tipo per la proprietà di dipendenza ereditata. Per essere un membro a pieno titolo del sistema di proprietà, tramite codice e markup, la classe che si aggiunge deve implementare questi membri pubblici.

  • Campo dell'identificatore di proprietà dipendente. Il valore dell'identificatore della proprietà di dipendenza è il valore restituito della chiamata AddOwner. Questo campo deve essere un campo di public static readonly di tipo DependencyProperty.

  • Wrapper CLR che implementa gli accessor get e set. Usando un wrapper di proprietà, gli utilizzatori delle dependency properties possono sia ottenere che impostare i valori delle proprietà di dipendenza, esattamente come farebbero con qualsiasi altra proprietà CLR. Le funzioni di accesso get e set interagiscono con il sistema di proprietà sottostante tramite chiamate DependencyObject.GetValue e DependencyObject.SetValue, passando l'identificatore della proprietà di dipendenza come parametro. Implementare il wrapper nello stesso modo in cui si registra una proprietà di dipendenza personalizzata. Per altre informazioni, vedere Proprietà di dipendenza personalizzate

Una classe che chiama AddOwner ha gli stessi requisiti per esporre il modello a oggetti della proprietà di dipendenza ereditata come classe che definisce una nuova proprietà di dipendenza personalizzata. Per maggiori informazioni, consultare Aggiungere un tipo di proprietario per una proprietà di dipendenza.

Metadati delle proprietà associate

In WPF, la maggior parte delle proprietà associate all'interfaccia utente sui tipi WPF è implementata come proprietà di dipendenza. Le proprietà associate implementate come proprietà di dipendenza supportano concetti relativi alle proprietà di dipendenza, ad esempio metadati che le classi derivate possono sovrascrivere. I metadati per una proprietà associata in genere non sono diversi da quelli di una proprietà di dipendenza. È possibile eseguire l'override del valore predefinito, dei callback delle modifiche delle proprietà e delle proprietà del framework WPF per la proprietà associata ereditata, nelle istanze della classe che esegue l'override. Per altre informazioni, vedere metadati delle proprietà allegate

Nota

Ricorda di usare sempre RegisterAttached per registrare le proprietà dove si specifica Inherits nei metadati. Anche se l'ereditarietà del valore della proprietà potrebbe funzionare per le proprietà di dipendenza non associate, il comportamento di ereditarietà dei valori per una proprietà non associata tramite determinate divisioni tra oggetti nell'albero di runtime non è definito. La proprietà Inherits non è rilevante per le proprietà non associate. Per altre informazioni, vedere RegisterAttached(String, Type, Type, PropertyMetadata)e la sezione osservazioni di Inherits.

Aggiungi una classe come proprietario di una proprietà associata

Per ereditare una proprietà associata da un'altra classe, ma esporla come proprietà di dipendenza non associata nella classe:

  • Chiama AddOwner per aggiungere la tua classe come proprietario della proprietà di dipendenza associata.

  • Assegnare il valore restituito della chiamata AddOwner a un campo public static readonly, da usare come identificatore della proprietà di dipendenza.

  • Definire un wrapper CLR, che aggiunge la proprietà come membro della classe e supporta l'uso di proprietà non collegata.

Vedere anche