Metadati delle proprietà di dipendenza
Il sistema delle proprietà di Windows Presentation Foundation (WPF) include un sistema di reportistica dei metadati che va oltre ciò che può essere riportato su una proprietà tramite reflection o caratteristiche generali del Common Language Runtime (CLR). I metadati per una proprietà di dipendenza possono anche essere assegnati in modo univoco dalla classe che definisce una proprietà di dipendenza, possono essere modificati quando la proprietà di dipendenza viene aggiunta a una classe diversa e possono essere sottoposti a override specificamente da tutte le classi derivate che ereditano la proprietà di dipendenza dalla classe di base che definisce.
Prerequisiti
In questo argomento si presuppone che le proprietà di dipendenza siano comprese dal punto di vista di un utente delle proprietà di dipendenza esistenti nelle classi WPF e che abbiate letto la Panoramica delle proprietà di dipendenza. Per seguire gli esempi in questo argomento, è necessario comprendere anche XAML e sapere come scrivere applicazioni WPF.
Modalità di utilizzo dei metadati delle proprietà di dipendenza
I metadati delle proprietà di dipendenza esistono come oggetto su cui è possibile eseguire query per esaminare le caratteristiche di una proprietà di dipendenza. Questi metadati sono accessibili spesso anche dal sistema di proprietà durante l'elaborazione di qualsiasi proprietà di dipendenza specificata. L'oggetto metadati per una proprietà di dipendenza può contenere i tipi di informazioni seguenti:
Valore predefinito per la proprietà di dipendenza, se non è possibile determinare altri valori per la proprietà di dipendenza in base al valore locale, allo stile, all'ereditarietà e così via. Per una descrizione approfondita del modo in cui i valori predefiniti partecipano alla precedenza usata dal sistema di proprietà durante l'assegnazione di valori per le proprietà di dipendenza, vedere precedenza del valore della proprietà di dipendenza.
Riferimenti alle implementazioni di callback che influiscono sulla coercizione o sui comportamenti di notifica delle modifiche in base al tipo di proprietario. Si noti che questi callback vengono spesso definiti con un livello di accesso non pubblico, pertanto ottenere i riferimenti effettivi dai metadati non è in genere possibile a meno che i riferimenti non si trovino nell'ambito di accesso consentito. Per ulteriori informazioni sui callback delle proprietà di dipendenza, consultare Callback e Convalida delle Proprietà di Dipendenza.
Se la proprietà di dipendenza in questione è considerata una proprietà a livello di framework WPF, i metadati potrebbero contenere caratteristiche delle proprietà di dipendenza a livello di framework WPF, che segnalano informazioni e stato per i servizi, ad esempio il motore di layout a livello di framework WPF e la logica di ereditarietà delle proprietà. Per altre informazioni su questo aspetto dei metadati delle proprietà di dipendenza, vedere Framework Property Metadata.
API dei metadati
Il tipo che segnala la maggior parte delle informazioni sui metadati usate dal sistema di proprietà è la classe PropertyMetadata. Le istanze dei metadati vengono specificate facoltativamente quando le proprietà di dipendenza sono registrate nel sistema di proprietà, e possono essere specificate nuovamente per i tipi aggiuntivi che si aggiungono come proprietari o sovrascrivono i metadati ereditati dalla definizione della proprietà di dipendenza della classe base. Nei casi in cui la registrazione di una proprietà non specifica i metadati, viene creato un PropertyMetadata predefinito con valori predefiniti per tale classe. I metadati registrati vengono restituiti come PropertyMetadata quando si chiamano i diversi overload di GetMetadata che recuperano i metadati da una proprietà dipendente in un'istanza di DependencyObject.
La classe PropertyMetadata viene quindi derivata da per fornire metadati più specifici per le divisioni architetturali, ad esempio le classi a livello di framework WPF. UIPropertyMetadata aggiunge la segnalazione di animazione e FrameworkPropertyMetadata fornisce le proprietà del framework WPF indicate nella sezione precedente. Quando le proprietà di dipendenza vengono registrate, possono essere registrate con queste classi derivate PropertyMetadata. Quando si esaminano i metadati, è possibile convertire il tipo di base PropertyMetadata nelle classi derivate per poter esaminare le proprietà più specifiche.
Nota
Le caratteristiche delle proprietà che possono essere specificate in FrameworkPropertyMetadata sono talvolta indicate in questa documentazione come "flag". Quando si creano nuove istanze di metadati da usare nelle registrazioni delle proprietà di dipendenza o nelle sostituzioni dei metadati, è necessario specificare questi valori tramite l'enumerazione di flag FrameworkPropertyMetadataOptions e quindi fornire valori eventualmente concatenati dell'enumerazione al costruttore FrameworkPropertyMetadata. Tuttavia, una volta costruite, queste caratteristiche di opzione vengono presentate all'interno di un FrameworkPropertyMetadata come una serie di proprietà booleane anziché come valore enumerato del processo di costruzione. Le proprietà booleane consentono di controllare ogni condizionale, anziché richiedere di applicare una maschera a un valore di enumerazione flag per ottenere le informazioni a cui si è interessati. Il costruttore usa il FrameworkPropertyMetadataOptions concatenato per mantenere ragionevole la lunghezza della firma del costruttore, mentre i metadati effettivamente costruiti espongono le proprietà discrete per rendere le interrogazioni sui metadati più intuitive.
Quando eseguire l'override dei metadati, quando derivare una classe
Il sistema di proprietà WPF offre funzionalità per modificare alcune caratteristiche delle proprietà dipendenti senza richiedere una completa reimplementazione. Questa operazione viene eseguita creando un'istanza differente di metadati di proprietà per la proprietà di dipendenza così come è definita su un determinato tipo. Si noti che la maggior parte delle proprietà di dipendenza esistenti non sono proprietà virtuali, pertanto la loro "reimplementazione" nelle classi ereditate può essere realizzata solo tramite l'occultamento del membro esistente.
Se lo scenario che si sta tentando di abilitare per una proprietà di dipendenza in un tipo non può essere eseguito modificando le caratteristiche delle proprietà di dipendenza esistenti, potrebbe essere necessario creare una classe derivata e quindi dichiarare una proprietà di dipendenza personalizzata nella classe derivata. Una proprietà di dipendenza personalizzata si comporta in modo identico alle proprietà di dipendenza definite dalle API WPF. Per altre informazioni sulle proprietà di dipendenza personalizzate, vedere proprietà di dipendenza personalizzate.
Una caratteristica rilevante di una proprietà di dipendenza che non è possibile sovrascrivere è il suo tipo di valore. Se si eredita una proprietà di dipendenza con il comportamento approssimativo necessario, ma è necessario un tipo diverso, sarà necessario implementare una proprietà di dipendenza personalizzata e collegare le proprietà tramite la conversione del tipo o un'altra implementazione nella classe personalizzata. Inoltre, non è possibile sostituire un ValidateValueCallbackesistente perché questo callback esiste nel campo di registrazione stesso e non all'interno dei relativi metadati.
Scenari per la modifica dei metadati esistenti
Se si utilizzano metadati di una proprietà di dipendenza esistente, uno scenario comune per la modifica dei metadati delle proprietà di dipendenza consiste nel modificare il valore predefinito. La modifica o l'aggiunta di callback delle proprietà di sistema è uno scenario più avanzato. Questa operazione può essere utile se l'implementazione di una classe derivata ha relazioni diverse tra le proprietà di dipendenza. Uno dei condizionali di avere un modello di programmazione che supporta sia il codice che l'utilizzo dichiarativo è che le proprietà devono abilitare l'impostazione in qualsiasi ordine. Pertanto, tutte le proprietà dipendenti devono essere impostate tempestivamente senza un contesto preciso e non possono basarsi sulla conoscenza di un ordine di impostazione come potrebbe essere nel contesto di un costruttore. Per ulteriori informazioni su questo aspetto del sistema di proprietà, vedere Callback e convalida delle proprietà di dipendenza. Si noti che i callback di convalida non fanno parte dei metadati; fanno parte dell'identificatore della proprietà di dipendenza. Non è pertanto possibile modificare i callback di convalida eseguendo l'override dei metadati.
In alcuni casi è anche possibile modificare le opzioni dei metadati delle proprietà a livello di framework WPF sulle proprietà di dipendenza esistenti. Queste opzioni comunicano certe condizioni note sulle proprietà del framework WPF ad altri processi del framework WPF, come il sistema di layout. L'impostazione delle opzioni viene in genere eseguita solo quando si registra una nuova proprietà di dipendenza, ma è anche possibile modificare i metadati delle proprietà a livello di framework WPF come parte di una chiamata OverrideMetadata o AddOwner. Per i valori specifici da usare e altre informazioni, vedere Framework Property Metadata. Per altre informazioni sul modo in cui queste opzioni devono essere impostate per una proprietà di dipendenza appena registrata, vedere Proprietà di dipendenza personalizzate.
Sovrascrittura dei metadati
Lo scopo dell'override dei metadati è principalmente quello di avere la possibilità di modificare i vari comportamenti derivati dai metadati applicati alla proprietà dipendente così com'è definita nel tipo. I motivi di ciò sono illustrati in modo più dettagliato nella sezione metadati. Per ulteriori informazioni, inclusi alcuni esempi di codice, consultare Come modificare i metadati per una proprietà di dipendenza.
I metadati delle proprietà possono essere forniti per una proprietà dipendente durante la chiamata di registrazione (Register). In molti casi, tuttavia, potrebbe essere necessario fornire metadati specifici del tipo alla classe quando eredita una proprietà di dipendenza. Puoi farlo chiamando il metodo OverrideMetadata. Per un esempio delle API WPF, la classe FrameworkElement è il tipo che registra prima la proprietà di dipendenza Focusable. Tuttavia, la classe Control esegue l'override dei metadati per la proprietà di dipendenza per fornire il proprio valore predefinito iniziale, modificandolo da false
a true
e in caso contrario viene nuovamente usata l'implementazione Focusable originale.
Quando si esegue l'override dei metadati, le diverse caratteristiche dei metadati vengono unite o sostituite.
PropertyChangedCallback è stato unito. Se si aggiunge un nuovo PropertyChangedCallback, il callback viene archiviato nei metadati. Se non si specifica un PropertyChangedCallback nell'override, il valore di PropertyChangedCallback viene promosso come riferimento dal predecessore più vicino che lo ha specificato nei metadati.
Il comportamento effettivo del sistema di proprietà per PropertyChangedCallback consiste nel fatto che le implementazioni per tutti i proprietari di metadati nella gerarchia vengono mantenute e aggiunte a una tabella, con ordine di esecuzione da parte del sistema di proprietà in quanto i callback della classe più derivata vengono richiamati per primi.
DefaultValue viene sostituito. Se non si specifica un DefaultValue nell'override, il valore di DefaultValue proviene dall'antenato più vicino che lo ha specificato nei metadati.
Le implementazioni CoerceValueCallback vengono sostituite. Quando si aggiunge un nuovo CoerceValueCallback, il callback viene archiviato nei metadati. Se non si specifica un CoerceValueCallback nell'override, il valore di CoerceValueCallback viene considerato come riferimento dall'antenato più vicino che lo ha specificato nei metadati.
Il comportamento del sistema di proprietà è che nei metadati immediati viene richiamato solo il CoerceValueCallback. Non vengono mantenuti riferimenti ad altre implementazioni di CoerceValueCallback nella gerarchia.
Questo comportamento viene implementato da Mergee può essere sottoposto a override nelle classi di metadati derivate.
Sostituzione dei metadati delle proprietà collegate
In WPF le proprietà associate vengono implementate come proprietà di dipendenza. Ciò significa che possiedono anche metadati delle proprietà, che possono essere modificati da ciascuna classe individualmente. Le considerazioni di ambito per una proprietà associata in WPF sono generalmente che qualsiasi DependencyObject può avere una proprietà associata impostata su di esso. Pertanto, qualsiasi classe derivata DependencyObject può eseguire l'override dei metadati per qualsiasi proprietà allegata, poiché potrebbe essere impostata su un'istanza della classe. Puoi eseguire l'override dei valori predefiniti, dei callback o delle proprietà di reporting delle caratteristiche a livello di framework WPF. Se la proprietà associata è impostata su un'istanza della tua classe, vengono applicate le caratteristiche di metadati delle proprietà di override. Ad esempio, è possibile eseguire l'override del valore predefinito, in modo che il valore di override venga segnalato come valore della proprietà associata nelle istanze della classe, ogni volta che la proprietà non è impostata in altro modo.
Nota
La proprietà Inherits non è rilevante per le proprietà associate.
Aggiungere una classe come proprietaria di una proprietà di dipendenza esistente
Una classe può aggiungersi come proprietario di una proprietà di dipendenza già registrata usando il metodo AddOwner. Ciò consente alla classe di usare una proprietà di dipendenza registrata originariamente per un tipo diverso. In genere, la classe di aggiunta non è una classe derivata del tipo che ha registrato per primo tale proprietà di dipendenza come proprietario. Effettivamente, ciò consente alla classe e alle sue classi derivate di "ereditare" un'implementazione della proprietà di dipendenza senza che la classe proprietaria originale e la classe che aggiunge si trovino nella stessa vera gerarchia di classi. Inoltre, la classe aggiungente (e tutte le classi derivate) possono quindi fornire metadati specifici per tipo per la proprietà dipendente originale.
Oltre ad aggiungersi come proprietaria tramite i metodi di utilità del sistema di proprietà, la classe che si sta aggiungendo deve dichiarare membri pubblici aggiuntivi su se stessa per rendere la proprietà di dipendenza un partecipante a pieno titolo nel sistema di proprietà, visibile sia nel codice che nel markup. Una classe che aggiunge una proprietà di dipendenza esistente ha le stesse responsabilità per quanto riguarda l'esposizione del modello a oggetti per tale proprietà di dipendenza come fa una classe che definisce una nuova proprietà di dipendenza personalizzata. Il primo membro di questo tipo da esporre è un campo identificatore per una proprietà di dipendenza. Questo campo deve essere un campo public static readonly
di tipo DependencyProperty, assegnato al valore restituito della chiamata AddOwner. Il secondo membro da definire è la proprietà "wrapper" di Common Language Runtime (CLR). Il wrapper rende molto più comodo gestire la proprietà di dipendenza nel codice (eviti le chiamate a SetValue ogni volta, poiché puoi effettuare tale chiamata una sola volta nel wrapper stesso). Il wrapper viene implementato in modo identico a come verrebbe implementato se si registrasse una proprietà di dipendenza personalizzata. Per ulteriori informazioni sull'implementazione di una proprietà di dipendenza, vedere Proprietà di dipendenza personalizzate e Aggiungere un tipo di proprietario per una proprietà di dipendenza.
Proprietà associate e AddOwner
È possibile chiamare AddOwner per una proprietà di dipendenza definita come proprietà allegata dalla classe proprietaria. In genere, il motivo di questa operazione consiste nell'esporre la proprietà associata in precedenza come proprietà di dipendenza non associata. Esporrai quindi il valore restituito di AddOwner come campo public static readonly
per permettere l'uso come identificatore della proprietà di dipendenza e definirai le proprietà "wrapper" appropriate in modo che la proprietà appaia nella tabella dei membri e supporti l'uso della proprietà non associata nella tua classe.
Vedere anche
- PropertyMetadata
- DependencyObject
- DependencyProperty
- GetMetadata
- Panoramica delle proprietà di dipendenza
- metadati delle proprietà di
Framework
.NET Desktop feedback