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 creazione di report dei metadati superano ciò che è disponibile tramite reflection o caratteristiche CLR (Common Language Runtime) generali. 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 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 si abbia letto 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 public modificatore di accesso o che si trovano all'interno dell'ambito di accesso consentito. Per altre informazioni sui callback delle proprietà di dipendenza, vedere 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 altre informazioni, vedere Metadati delle proprietà del framework.

API dei metadati

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

  • Tipi che registrano le proprietà di dipendenza con il sistema di 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 PropertyMetadata oggetto con valori predefiniti per tale tipo alla proprietà di dipendenza.

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

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 PropertyMetadata classi derivate. Anche se restituisce GetMetadata un PropertyMetadata oggetto, 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 FrameworkPropertyMetadata di , è possibile passare un'istanza del tipo FrameworkPropertyMetadataOptions di enumerazione nel FrameworkPropertyMetadata costruttore. FrameworkPropertyMetadataOptions consente di specificare i flag di metadati in combinazione bit per bit. Usa FrameworkPropertyMetadata FrameworkPropertyMetadataOptions per mantenere ragionevole la lunghezza della firma del costruttore. Nella registrazione delle proprietà di dipendenza, i flag di metadati impostati in FrameworkPropertyMetadataOptions vengono esposti all'interno di come Boolean proprietà anziché come combinazione bit per bit di flag, per rendere più intuitiva l'esecuzione FrameworkPropertyMetadata di query sulle caratteristiche dei metadati.

Eseguire l'override 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 eseguire l'override è 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.

  • Modifica o aggiunta di callback di modifica delle proprietà, che potrebbero essere necessari se una proprietà di dipendenza ereditata interagisce con altre proprietà di dipendenza in modo diverso rispetto all'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 Callback e convalida delle proprietà di dipendenza.

  • 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 specificarle in OverrideMetadata o AddOwner chiamate. Per altre informazioni sull'override dei metadati delle proprietà del framework, vedere Specifica di 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 altre informazioni, vedere Callback dei valori di convalida.

Override dei metadati

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

Un esempio di proprietà di dipendenza WPF è Focusable. La FrameworkElement classe registra Focusable. La Control classe deriva da FrameworkElement, eredita la Focusable proprietà di dipendenza 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 , DefaultValueil nuovo valore sostituirà il valore predefinito esistente. Se non si specifica un oggetto DefaultValue nei metadati di override, il valore proviene dal predecessore più vicino specificato DefaultValue nei metadati.

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

  • Per un oggetto CoerceValueCallback, il nuovo valore sostituirà il valore esistente CoerceValueCallback . Se non si specifica un oggetto CoerceValueCallback nei metadati di override, il valore proviene dal predecessore più vicino specificato CoerceValueCallback nei metadati.

Nota

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

Aggiungere una classe come proprietario

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

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

  • Wrapper CLR che implementa get le funzioni di accesso e set . Usando un wrapper di proprietà, i consumer di proprietà di dipendenza possono ottenere o impostare i valori delle proprietà di dipendenza, esattamente come qualsiasi altra proprietà CLR. Le get funzioni di accesso e set interagiscono con il sistema di proprietà sottostante tramite DependencyObject.GetValue e DependencyObject.SetValue chiamate, 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 altre informazioni, vedere Aggiungere un tipo di proprietario per una proprietà di dipendenza.

Metadati delle proprietà associate

In WPF la maggior parte delle proprietà associate correlate all'interfaccia utente sui tipi WPF viene 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 eseguire l'override. 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 di override. Per altre informazioni, vedere Metadati delle proprietà associate

Nota

Usare RegisterAttached sempre per registrare le proprietà in cui si specificano Inherits i 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 oggetto-oggetto nell'albero di runtime non è definito. La Inherits proprietà non è rilevante per le proprietà non associate. Per altre informazioni, vedere RegisterAttached(String, Type, Type, PropertyMetadata)e la sezione osservazioni di Inherits.

Aggiungere 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:

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

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

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

Vedi anche