Definire tipi personalizzati da usare con i servizi XAML .NET
Quando definisci tipi personalizzati che sono oggetti business o sono tipi che non hanno una dipendenza da framework specifici, puoi seguire alcune procedure consigliate per XAML. Se segui queste procedure, i servizi XAML .NET e i relativi lettori XAML e writer XAML possono individuare le caratteristiche XAML del tipo e assegnargli una rappresentazione appropriata in un flusso di nodi XAML usando il sistema di tipi XAML. In questo argomento vengono descritte le procedure consigliate per definizioni di tipi, definizioni di membri e attributi CLR di tipi o membri.
Modelli di costruttore e definizioni di tipi per XAML
Per essere creata un'istanza come elemento oggetto in XAML, una classe personalizzata deve soddisfare i requisiti seguenti:
La classe personalizzata deve essere pubblica e deve esporre un costruttore pubblico senza parametri. Per le note relative alle strutture, vedere la sezione seguente.
La classe personalizzata non deve essere una classe annidata. Il "punto" aggiuntivo nel percorso full-name rende ambigua la divisione class-namespace e interferisce con altre funzionalità XAML, ad esempio le proprietà associate. Se è possibile creare un'istanza di un oggetto come elemento oggetto, l'oggetto creato può riempire il formato dell'elemento proprietà di qualsiasi proprietà che accetta l'oggetto come tipo sottostante.
È comunque possibile fornire valori oggetto per i tipi che non soddisfano questi criteri, se si abilita un convertitore di valori. Per altre informazioni, vedere convertitori di tipi di e estensioni di markup per XAML.
Strutture
Le strutture sono sempre in grado di essere costruite in XAML, tramite la definizione CLR. Questo perché un compilatore CLR crea in modo implicito un costruttore senza parametri per una struttura. Questo costruttore inizializza tutti i valori delle proprietà in base alle impostazioni predefinite.
In alcuni casi, il comportamento di costruzione predefinito per una struttura non è auspicabile. Ciò potrebbe essere dovuto al fatto che la struttura è destinata a riempire i valori e a funzionare concettualmente come unione. Come unione, i valori contenuti potrebbero avere interpretazioni che si escludono a vicenda e pertanto nessuna delle relative proprietà è impostabile. Un esempio di tale struttura nel vocabolario WPF è GridLength. Tali strutture devono implementare un convertitore di tipi in modo che i valori possano essere espressi in forma di attributo, usando convenzioni di stringa che creano le diverse interpretazioni o modalità dei valori della struttura. La struttura deve esporre anche un comportamento simile per la costruzione del codice tramite un costruttore senza parametri.
Interfacce
Le interfacce possono essere usate come tipi sottostanti di membri. Il sistema di tipi XAML controlla l'elenco assegnabile e prevede che l'oggetto fornito come valore possa essere assegnato all'interfaccia. Non esiste alcun concetto di come l'interfaccia deve essere presentata come tipo XAML, purché un tipo assegnabile pertinente supporti i requisiti di costruzione XAML.
Metodi factory
I metodi factory sono una funzionalità XAML 2009. Modificano il principio XAML che gli oggetti devono avere costruttori senza parametri. I metodi factory non sono documentati in questo articolo. Vedere direttiva x:FactoryMethod.
Enumerazioni
Le enumerazioni hanno un comportamento di conversione dei tipi nativi XAML. I nomi delle costanti di enumerazione specificati in XAML vengono risolti in base al tipo di enumerazione sottostante e restituiscono il valore di enumerazione a un writer di oggetti XAML.
XAML supporta un utilizzo in stile flag per le enumerazioni con FlagsAttribute applicato. Per altre informazioni, vedere sintassi XAML in dettaglio. (sintassi XAML in dettaglio viene scritta per il pubblico WPF, ma la maggior parte delle informazioni in questo argomento è rilevante per XAML che non è specifico di un framework di implementazione specifico.
Definizioni dei membri
I tipi possono definire i membri per l'utilizzo di XAML. È possibile che i tipi definisci membri utilizzabili da XAML anche se tale tipo specifico non è utilizzabile da XAML. Ciò è possibile a causa dell'ereditarietà CLR. Fino a quando un tipo che eredita il membro supporta l'utilizzo xaml come tipo e il membro supporta l'utilizzo XAML per il tipo sottostante o ha una sintassi XAML nativa disponibile, tale membro è utilizzabile da XAML.
Proprietà
Se definisci le proprietà come proprietà CLR pubbliche usando i tipici get
CLR e set
modelli di funzione di accesso e le parole chiave appropriate per il linguaggio, il sistema di tipi XAML può segnalare la proprietà come membro con le informazioni appropriate fornite per le proprietà XamlMember, ad esempio IsReadPublic e IsWritePublic.
Le proprietà specifiche possono abilitare una sintassi di testo applicando TypeConverterAttribute. Per altre informazioni, vedere convertitori di tipi di e estensioni di markup per XAML.
In assenza di una sintassi di testo o di una conversione XAML nativa e in assenza di ulteriori informazioni indirette, ad esempio un utilizzo dell'estensione di markup, il tipo di una proprietà (TargetType nel sistema di tipi XAML) deve essere in grado di restituire un'istanza a un writer di oggetti XAML considerando il tipo di destinazione come tipo CLR.
Se si usa XAML 2009, x:Reference Markup Extension può essere usato per fornire valori se le considerazioni precedenti non vengono soddisfatte; Tuttavia, questo è più di un problema di utilizzo rispetto a un problema di definizione del tipo.
Avvenimenti
Se definisci eventi come evento CLR pubblico, il sistema di tipi XAML può segnalare l'evento come membro con IsEvent come true
. Collegare i gestori eventi non rientra nell'ambito delle funzionalità dei servizi XAML .NET; il cablaggio viene lasciato a framework e implementazioni specifici.
Metodi
Il codice inline per i metodi non è una funzionalità XAML predefinita. Nella maggior parte dei casi, non fai riferimento direttamente ai membri del metodo da XAML e il ruolo dei metodi in XAML è solo quello di fornire supporto per modelli XAML specifici. direttiva x:FactoryMethod è un'eccezione.
Campi
Le linee guida per la progettazione CLR sconsigliano i campi non statico. Per i campi statici, è possibile accedere ai valori dei campi statici solo tramite x:Static Markup Extension; in questo caso non si esegue alcuna operazione speciale nella definizione CLR per esporre un campo per gli utilizzi di x:Static.
Membri associabili
I membri associabili vengono esposti a XAML tramite un modello di metodo di accesso su un tipo di definizione. Il tipo di definizione stesso non deve essere utilizzabile da XAML come oggetto. In effetti, un modello comune consiste nel dichiarare una classe del servizio il cui ruolo è proprietario del membro associabile e implementare i comportamenti correlati, ma non serve altre funzioni, ad esempio una rappresentazione dell'interfaccia utente. Per le sezioni seguenti, il segnaposto PropertyName rappresenta il nome del membro associabile. Tale nome deve essere valido nel XamlName Grammar.
Prestare attenzione alle collisioni di nomi tra questi modelli e altri metodi di un tipo. Se esiste un membro che corrisponde a uno dei modelli, può essere interpretato come un percorso di utilizzo dei membri associabile da un processore XAML anche se questa non era la tua intenzione.
Funzione di accesso GetPropertyName
La firma per la funzione di accesso GetPropertyName
deve essere:
public static object GetPropertyName(object target)
L'oggetto
target
può essere specificato come tipo più specifico nell'implementazione. È possibile usarlo per definire l'ambito dell'utilizzo del membro collegabile; gli utilizzi all'esterno dell'ambito previsto genereranno eccezioni di cast non valide che vengono quindi rilevate da un errore di analisi XAML. Il nome del parametrotarget
non è un requisito, ma è denominatotarget
per convenzione nella maggior parte delle implementazioni.Il valore restituito può essere specificato come tipo più specifico nell'implementazione.
Per supportare una sintassi di testo abilitata TypeConverter per l'utilizzo degli attributi del membro associabile, applicare TypeConverterAttribute alla funzione di accesso GetPropertyName
. L'applicazione al get
invece del set
può sembrare non intuitiva; Tuttavia, questa convenzione può supportare il concetto di membri associabili di sola lettura che sono serializzabili, che è utile negli scenari di progettazione.
Funzione di accesso SetPropertyName
La firma per la funzione di accesso SetPropertyName
deve essere:
public static void SetPropertyName(object target, object value)
L'oggetto
target
può essere specificato come tipo più specifico nell'implementazione, con la stessa logica e le stesse conseguenze descritte nella sezione precedente.L'oggetto
value
può essere specificato come tipo più specifico nell'implementazione.
Tenere presente che il valore per questo metodo è l'input proveniente dall'utilizzo xaml, in genere nel formato attributo. Dal formato attributo deve essere presente il supporto del convertitore di valori per una sintassi di testo e l'attributo nella funzione di accesso GetPropertyName
.
Archivi membri associabili
I metodi della funzione di accesso in genere non sono sufficienti per fornire un mezzo per inserire i valori dei membri associabili in un oggetto grafico o per recuperare i valori dall'oggetto grafico e serializzarli correttamente. Per fornire questa funzionalità, gli oggetti target
nelle firme della funzione di accesso precedenti devono essere in grado di archiviare i valori. Il meccanismo di archiviazione deve essere coerente con il principio del membro associabile che il membro è collegabile alle destinazioni in cui il membro associabile non è incluso nell'elenco dei membri. I servizi XAML .NET forniscono una tecnica di implementazione per gli archivi membri associabili tramite le API IAttachedPropertyStore e AttachablePropertyServices.
IAttachedPropertyStore viene usato dai writer XAML per individuare l'implementazione dell'archivio e deve essere implementato nel tipo che rappresenta il target
delle funzioni di accesso. Le API AttachablePropertyServices statiche vengono usate all'interno del corpo delle funzioni di accesso e fanno riferimento al membro associabile dal relativo AttachableMemberIdentifier.
attributi CLR XAML-Related
L'attribuzione corretta di tipi, membri e assembly è importante per segnalare le informazioni sul sistema dei tipi XAML ai servizi XAML .NET. La segnalazione delle informazioni sul sistema dei tipi XAML è rilevante se si applica una delle situazioni seguenti:
- Intendi usare i tuoi tipi con i sistemi XAML direttamente basati su lettori XAML e writer XAML dei servizi .NET.
- Definisci o usi un framework XAML basato su lettori XAML e writer XAML.
Per un elenco di ogni attributo correlato a XAML pertinente per il supporto XAML dei tipi personalizzati, vedi XAML-Related attributi CLR per tipi e librerie personalizzati.
Uso
L'utilizzo di tipi personalizzati richiede che l'autore del markup debba eseguire il mapping di un prefisso per l'assembly e lo spazio dei nomi CLR che contengono il tipo personalizzato. Questa procedura non è documentata in questo argomento.
Livello di accesso
XAML consente di caricare e creare istanze di tipi con un livello di accesso internal
. Questa funzionalità viene fornita in modo che il codice utente possa definire i propri tipi e quindi creare un'istanza di tali classi dal markup che fa anche parte dello stesso ambito di codice utente.
Un esempio di WPF è ogni volta che il codice utente definisce un UserControl destinato a effettuare il refactoring di un comportamento dell'interfaccia utente, ma non come parte di qualsiasi possibile meccanismo di estensione che potrebbe essere implicito dichiarando la classe di supporto con public
livello di accesso. Un UserControl di questo tipo può essere dichiarato con accesso internal
se il codice di supporto viene compilato nello stesso assembly da cui viene fatto riferimento come tipo XAML.
Per un'applicazione che carica XAML con attendibilità totale e usa XamlObjectWriter, il caricamento di classi con internal
livello di accesso è sempre abilitato.
Per un'applicazione che carica XAML con attendibilità parziale, puoi controllare le caratteristiche del livello di accesso usando l'API XamlAccessLevel. Inoltre, i meccanismi di rinvio (ad esempio il sistema di modelli WPF) devono essere in grado di propagare le autorizzazioni a livello di accesso e conservarle per le valutazioni di runtime finali; questo viene gestito internamente passando le informazioni di XamlAccessLevel.
Implementazione WPF
WPF XAML usa un modello di accesso parzialmente attendibile in cui se BAML viene caricato con attendibilità parziale, l'accesso è limitato ai AssemblyAccessTo per l'assembly che è l'origine BAML. Per il differimento, WPF usa IXamlObjectWriterFactory.GetParentSettings come meccanismo per passare le informazioni sul livello di accesso.
Nella terminologia XAML WPF un tipo interno è un tipo definito dallo stesso assembly che include anche il codice XAML di riferimento. Un tipo di questo tipo può essere mappato tramite uno spazio dei nomi XAML che omette deliberatamente la parte assembly= di un mapping, ad esempio xmlns:local="clr-namespace:WPFApplication1"
. Se BAML fa riferimento a un tipo interno e tale tipo ha internal
livello di accesso, viene generata una classe GeneratedInternalTypeHelper
per l'assembly. Se si desidera evitare GeneratedInternalTypeHelper
, è necessario usare public
livello di accesso oppure considerare la classe pertinente in un assembly separato e rendere tale assembly dipendente.
Vedere anche
- XAML-Related attributi CLR per i tipi e le librerie personalizzati
- dei servizi XAML
.NET Desktop feedback