Condividi tramite


Panoramica dei convertitori di tipi per XAML

I convertitori di tipi forniscono la logica per assistere un writer di oggetti che esegue una conversione da una stringa nel markup XAML in particolari oggetti in un oggetto grafico. Nei servizi XAML di .NET Framework, il convertitore di tipi deve essere una classe che deriva da TypeConverter. Alcuni convertitori supportano inoltre il percorso di salvataggio XAML e possono essere utilizzati per serializzare un oggetto in un formato stringa nel markup di serializzazione. In questo argomento viene descritto come e quando vengono richiamati i convertitori di tipi in XAML e vengono forniti consigli di implementazione per gli override del metodo di TypeConverter.

Nel presente argomento sono contenute le seguenti sezioni.

  • Concetti relativi alla conversione di tipi
  • Implementazione di un convertitore di tipi
  • Applicazione di TypeConverterAttribute
  • Accesso al contesto del provider di servizi da un'implementazione dell'estensione di markup
  • Convertitori di tipi nel flusso del nodo XAML
  • Argomenti correlati

Concetti relativi alla conversione di tipi

Nelle sezioni seguenti vengono spiegati i concetti di base riguardanti il modo in cui XAML utilizza le stringhe e il modo in cui i writer di oggetti nei servizi XAML di .NET Framework utilizzano i convertitori di tipi per elaborare alcuni dei valori stringa rilevati in un'origine XAML.

Valori XAML e di stringa

Quando si imposta un valore dell'attributo in un file XAML, il tipo iniziale di tale valore è una stringa in senso generale e un valore dell'attributo di stringa in XML. Anche altre primitive, ad esempio Double, sono inizialmente stringhe per un processore XAML.

Nella maggior parte dei casi, un processore XAML deve disporre di due informazioni per elaborare un valore di attributo. La prima informazione è il tipo di valore della proprietà che si imposta. Qualsiasi stringa che definisce un valore di attributo e che viene elaborata in XAML deve essere convertita o risolta in un valore di quel tipo. Se il valore è una primitiva riconosciuta dal parser XAML (ad esempio un valore numerico), viene eseguito un tentativo di conversione diretta della stringa. Se il valore dell'attributo fa riferimento a un'enumerazione, nella stringa specificata viene verificata la corrispondenza del nome con una costante denominata in tale enumerazione. Se il valore non è né una primitiva riconosciuta dal parser né il nome di una costante di un'enumerazione, il tipo applicabile deve essere in grado di fornire un valore o un riferimento basato su una stringa convertita.

NotaNota

Le direttive del linguaggio XAML non utilizzano convertitori di tipi.

Convertitori di tipi ed estensioni di markup

Gli utilizzi di estensioni di markup devono essere gestiti da un processore XAML prima che questo verifichi il tipo di proprietà e altre considerazioni. Ad esempio, se una proprietà impostata come attributo viene associata normalmente a una conversione di tipi, ma in un caso particolare viene impostata mediante un utilizzo dell'estensione di markup, viene innanzitutto elaborato il comportamento dell'estensione di markup. Una situazione comune che richiede un'estensione di markup è la creazione di un riferimento a un oggetto già esistente. Per questo scenario, un convertitore di tipi senza stato può solo generare una nuova istanza, che non necessariamente è appropriata. Per ulteriori informazioni sulle estensioni di markup, vedere Panoramica delle estensioni di markup per XAML.

Convertitori di tipi nativi

Nell'implementazione dei servizi XAML WPF e .NET Framework esistono determinati tipi CLR che dispongono di una gestione nativa della conversione del tipo, tuttavia tali tipi CLR non sono propriamente considerati primitive. Un esempio dei tipi in questione è DateTime. Un motivo consiste nel funzionamento dell'architettura di .NET Framework: il tipo DateTime è definito in mscorlib, la libreria più elementare di .NET. Poiché non è consentito assegnare a DateTime un attributo fornito da un altro assembly che introduce una dipendenza (TypeConverterAttribute è fornito da System), il consueto meccanismo di individuazione del convertitore di tipi mediante assegnazione di attributi non può essere supportato. Il parser XAML dispone invece di un elenco di tipi che necessitano di elaborazione nativa ed elabora tali tipi con modalità analoghe all'elaborazione delle primitive effettive. Nel caso di DateTime, l'elaborazione comporta una chiamata a Parse.

Implementazione di un convertitore di tipi

Nelle sezioni seguenti viene discussa l'API della classe TypeConverter.

TypeConverter

Nei servizi XAML di .NET Framework tutti i convertitori di tipi utilizzati per XAML sono classi derivanti dalla classe di base TypeConverter. La classe TypeConverter era presente nelle versioni di .NET Framework precedenti all'introduzione di XAML; in origine, uno degli scenari di TypeConverter consisteva nel fornire la conversione delle stringhe per gli editor delle proprietà nelle finestre di progettazione visiva.

Per XAML, il ruolo di TypeConverter viene esteso. In XAML, TypeConverter è la classe di base che fornisce il supporto per determinate conversioni da stringa e in stringa. La conversione da stringa consente l'analisi di un valore dell'attributo di stringa da XAML. La conversione in stringa può consentire l'elaborazione di un valore di runtime di una particolare proprietà dell'oggetto in un attributo in XAML per la serializzazione.

TypeConverter definisce quattro membri che sono rilevanti per la conversione da e in stringa al fine di elaborare la sintassi XAML:

Di questi membri, il metodo più importante è ConvertFrom, che converte la stringa di input nel tipo di oggetto richiesto. È possibile implementare il metodo ConvertFrom per convertire una più vasta gamma di tipi nel tipo di destinazione previsto dal convertitore. Il metodo assolve pertanto scopi che si estendono oltre quelli definiti per XAML, quale il supporto delle conversioni in fase di esecuzione. Tuttavia, per quanto riguarda XAML, l'unico elemento importante è il percorso del codice che consente di elaborare un input String.

Il secondo metodo in ordine di importanza è ConvertTo. Se un'applicazione viene convertita in una rappresentazione del markup (quando ad esempio viene salvata in XAML come file), ConvertTo è interessato dallo scenario più ampio della creazione di una rappresentazione di markup da parte di writer di testi XAML. In questo caso, il percorso di codice importante per XAML è il passaggio di destinationType di String da parte del chiamante.

CanConvertTo e CanConvertFrom sono metodi di supporto utilizzati quando un servizio esegue una query sulle funzionalità dell'implementazione di TypeConverter. È necessario implementare questi metodi per restituire true per i casi specifici del tipo supportati dai metodi di conversione equivalenti del convertitore. Per XAML, si tratta in genere del tipo String.

Informazioni relative alle impostazioni cultura e convertitori di tipi per XAML

Ogni implementazione di TypeConverter può interpretare in modo univoco il concetto di stringa valida per una conversione e può quindi utilizzare o ignorare la descrizione del tipo passata come parametri. Una considerazione importante circa le impostazioni cultura e la conversione di tipi XAML: benché l'utilizzo di stringhe localizzabili come valori di attributo sia supportato da XAML, non è possibile utilizzare tali stringhe come input del convertitore di tipi con requisiti specifici per le impostazioni cultura. Questa limitazione è dovuta al fatto che i convertitori di tipi per i valori di attributo XAML implicano necessariamente un comportamento di elaborazione XAML basato su un'unica lingua che utilizza le impostazioni cultura en-US. Per ulteriori informazioni sui motivi legati alla progettazione di tale limitazione, vedere la specifica del linguaggio XAML ([MS-XAML] - la pagina potrebbe essere in inglese) o WPF Globalization and Localization Overview.

Un esempio delle problematiche che possono presentarsi con le impostazioni cultura è rappresentato dal separatore decimale per i numeri in formato stringa, che per alcune impostazioni cultura è la virgola anziché il punto. Tale utilizzo è in conflitto con il comportamento di molti convertitori di tipi esistenti, che prevede l'utilizzo della virgola come delimitatore. Il passaggio di impostazioni cultura tramite xml:lang nel codice XAML adiacente non risolve il problema.

Implementazione di ConvertFrom

Per essere utilizzabile come implementazione di TypeConverter che supporti XAML, il metodo ConvertFrom per tale convertitore deve accettare una stringa come parametro value. Se la stringa ha un formato valido e può essere convertita dall'implementazione di TypeConverter, l'oggetto restituito deve supportare un cast nel tipo previsto dalla proprietà. In caso contrario, l'implementazione ConvertFrom deve restituire null.

Ogni implementazione di TypeConverter può interpretare in modo univoco il concetto di stringa valida per una conversione e può quindi utilizzare o ignorare i contesti della descrizione del tipo o delle impostazioni cultura passati come parametri. Tuttavia, l'elaborazione della sintassi XAML di WPF potrebbe non passare i valori al contesto della descrizione del tipo in tutti i casi e potrebbe perfino non passare le impostazioni cultura basate su xml:lang.

NotaNota

Non utilizzare le parentesi graffe ({}), in particolare quella di apertura ({), come elemento del formato stringa.Questi caratteri vengono utilizzati esclusivamente come punti di ingresso e di uscita di una sequenza di estensione del markup.

È opportuno generare un'eccezione quando il convertitore di tipi deve avere accesso a un servizio XAML dal writer di servizi XAML di .NET Framework, ma la chiamata a GetService eseguita rispetto al contesto non restituisce tale servizio.

Implementazione di ConvertTo

ConvertTo viene potenzialmente utilizzato per il supporto della serializzazione. Il supporto della serializzazione tramite ConvertTo per il tipo personalizzato e il relativo convertitore di tipi non è un requisito assoluto. Tuttavia, se si implementa un controllo o si utilizza la serializzazione come parte delle funzionalità o della progettazione della classe, sarà necessario implementare ConvertTo.

Per poter essere utilizzato come implementazione di TypeConverter che supporta XAML, il metodo ConvertTo per tale convertitore deve accettare un'istanza del tipo (o un valore) supportata come parametro value. Quando il parametro destinationType è di tipo String, deve essere possibile eseguire il cast dell'oggetto restituito come String. La stringa restituita deve rappresentare un valore serializzato di value. In teoria, il formato di serializzazione scelto deve essere in grado di generare lo stesso valore che si otterrebbe se quella stringa venisse passata all'implementazione di ConvertFrom dello stesso convertitore, senza perdite significative di informazioni.

Se il valore non può essere serializzato o il convertitore non supporta la serializzazione, l'implementazione di ConvertTo deve restituire null e può generare un'eccezione. Tuttavia, se si generano eccezioni, sarà necessario segnalare l'impossibilità di utilizzare tale conversione nell'implementazione di CanConvertTo in modo da supportare un controllo preventivo con CanConvertTo, che rappresenta la procedura consigliata per evitare eccezioni.

Se il parametro destinationType non è di tipo String, è possibile scegliere la gestione del convertitore. In genere, viene ripristinata la gestione dell'implementazione di base, che nella forma base di ConvertTo genera un'eccezione specifica.

È opportuno generare un'eccezione quando il convertitore di tipi deve avere accesso a un servizio XAML dal writer di servizi XAML di .NET Framework, ma la chiamata a GetService eseguita rispetto al contesto non restituisce tale servizio.

Implementazione di CanConvertFrom

L'implementazione di CanConvertFrom deve restituire true per un oggetto sourceType di tipo String; in caso contrario, deve rinviare all'implementazione di base. Non generare eccezioni da CanConvertFrom.

Implementazione di CanConvertTo

L'implementazione di CanConvertTo deve restituire true per un oggetto destinationType di tipo String; in caso contrario, deve rinviare all'implementazione di base. Non generare eccezioni da CanConvertTo.

Applicazione di TypeConverterAttribute

Affinché il convertitore di tipi personalizzato venga utilizzato come convertitore di tipi operativo per una classe personalizzata dall'elaborazione dei servizi XAML di .NET Framework, è necessario applicare l'.NET Framework attribute TypeConverterAttribute alla definizione della classe. L'oggetto ConverterTypeName specificato tramite l'attributo deve corrispondere al nome di tipo del convertitore dei tipi personalizzato. Se si applica questo attributo, quando un processore XAML gestisce valori per i quali il tipo di proprietà utilizza il tipo di classe personalizzato, può immettere stringhe e restituire istanze di oggetti.

È anche possibile fornire un convertitore dei tipi per le singole proprietà. Anziché applicare un .NET Framework attribute TypeConverterAttribute alla definizione della classe, applicarlo a una definizione della proprietà (la definizione principale, non le implementazioni di get/set al suo interno). Il tipo della proprietà deve corrispondere al tipo elaborato dal convertitore dei tipi personalizzato. Se questo attributo viene applicato, quando un processore XAML gestisce i valori di quella proprietà, può elaborare stringhe di input e restituire istanze di oggetti. La tecnica del convertitore dei tipi per singole proprietà risulta particolarmente utile se si sceglie di utilizzare un tipo di proprietà dall'Microsoft .NET Framework o da qualche altra libreria in cui non è possibile controllare la definizione della classe né applicare un oggetto TypeConverterAttribute.

Per fornire un comportamento di conversione di tipi per un membro associato personalizzato, applicare TypeConverterAttribute al metodo della funzione di accesso Get del modello di implementazione per il membro associato.

Accesso al contesto del provider di servizi da un'implementazione dell'estensione di markup

I servizi disponibili sono gli stessi per qualsiasi convertitore di valori. L'unica differenza risiede nel modo in cui ogni convertitore di valori riceve il contesto del servizio. L'accesso ai servizi e i servizi disponibili sono illustrati nell'argomento Convertitori di tipi ed estensioni di markup per XAML.

Convertitori di tipi nel flusso del nodo XAML

Se si utilizza un flusso del nodo XAML, l'azione o il risultato finale di un convertitore di tipi non è ancora eseguito. In un percorso di caricamento, la stringa dell'attributo che necessita eventualmente di una conversione di tipi ai fini del caricamento resta sotto forma di valore testuale all'interno di un membro iniziale e di un membro finale. Il convertitore di tipi eventualmente necessario per questa operazione può essere determinato tramite la proprietà XamlMember.TypeConverter. Tuttavia, per ottenere un valore valido da XamlMember.TypeConverter è necessario avere un contesto dello schema XAML, che può accedere a tali informazioni tramite il membro sottostante, o il tipo del valore dell'oggetto utilizzato dal membro. Il richiamo del comportamento di conversione di tipi richiede anche il contesto dello schema XAML poiché ciò richiede il mapping dei tipi e la creazione di un'istanza del convertitore.

Vedere anche

Riferimenti

TypeConverterAttribute

Concetti

Cenni preliminari su XAML (WPF)

Altre risorse

Convertitori di tipi ed estensioni di markup per XAML