Provider di funzionalità e connettori di funzionalità

Qualsiasi oggetto progettabile in un'applicazione Windows Presentation Foundation (WPF) o Silverlight può esporre un numero arbitrario di estensioni della finestra di progettazione. Nell'argomento seguente sono discusse le funzionalità dei provider di funzionalità e il ruolo dei connettori di funzionalità nel fornire funzionalità in fase di progettazione.

Nozioni fondamentali sui provider di funzionalità e i connettori di funzionalità

Un provider di funzionalità è un tipo leggero che fornisce funzionalità aggiuntive in fase di progettazione per un oggetto. Alcuni provider di funzionalità possono fornire semplicemente informazioni sui sottocomponenti e non richiedono azioni da parte della finestra di progettazione. Altri provider di funzionalità consentono di aggiungere voci di menu al menu di scelta rapida della finestra di progettazione dell'oggetto, creare strumenti decorativi personalizzati per ridimensionare o modificare o ridefinire il trascinamento di oggetti nella finestra di progettazione.

I provider di funzionalità sono implementati derivando direttamente dalla classe FeatureProvider oppure da una classe che a sua volta deriva da FeatureProvider, ad esempio AdornerProvider e ContextMenuProvider. I provider di funzionalità sono progettati per essere leggeri e non devono tentare di salvare lo stato tra istanze.

Un connettore di funzionalità gestisce uno o più provider di funzionalità per un dato oggetto. I connettori di funzionalità consentono di pubblicare servizi nuovi tramite un provider di servizi e possono ascoltare eventi nella finestra di progettazione, ad esempio modifiche di selezione. I connettori di funzionalità sono implementati derivando una nuova classe dalla classe FeatureConnector<TFeatureProviderType> o dalla classe PolicyDrivenFeatureConnector<TFeatureProviderType>.

Provider di funzionalità

Un provider di funzionalità deve essere un punto leggero di estensibilità. Scenari comuni che comportano estensibilità di progettazione favoriscono la derivazione dalle classi esistenti del provider di funzionalità anziché la creazione di nuovi connettori di funzionalità. I provider di funzionalità non devono salvare lo stato, perché vengono creati e distrutti più volte.

I provider di funzionalità sono completamente gestiti dai connettori di funzionalità e sono associati a oggetti attraverso i metadati, in particolare FeatureAttribute. Il connettore di funzionalità individua i tipi FeatureProvider da questi metadati. La classe FeatureManager identifica il connettore di funzionalità richiesto per ciascun provider di funzionalità scoperto.

Le implementazioni comuni dei provider di funzionalità includono strumenti decorativi di selezione, verbi ed editor di proprietà. Per ulteriori informazioni, vedere Procedura dettagliata: creazione di uno strumento decorativo visuale in fase di progettazione.

Esempi di provider di funzionalità

Nell'illustrazione seguente viene mostrata una finestra di progettazione visiva e i tipi di funzionalità che possono rientrare nelle categorie provider di funzionalità o connettore di funzionalità. Notare che l'illustrazione è solo un esempio di come alcune delle funzionalità di una finestra di progettazione potrebbero essere implementate.

Esempio di connettori e provider di funzionalità

Nella tabella seguente sono elencati i provider di funzionalità dai quali è possibile derivare.

Provider di funzionalità

Descrizione

AdornerProvider

Aggiunge strumenti decorativi alla superficie della finestra di progettazione.

PrimarySelectionAdornerProvider

Aggiunge strumenti decorativi visualizzati per la selezione primaria.

ContextMenuProvider

Definisce un set di voci di menu visualizzate in un menu di scelta rapida.

PrimarySelectionContextMenuProvider

Definisce un set di voci di menu visualizzate per la selezione corrente.

PolicyDrivenFeatureConnector<TFeatureProviderType>.ItemFeatureProvider

Identifica i provider di funzionalità che appartengono a un determinato elemento.

TaskProvider

Aggiunge attività allo strumento attivo.

PrimarySelectionTaskProvider

Fornisce un insieme di attività che sono disponibili dallo strumento di selezione quando una classe è inclusa nella selezione primaria.

DesignModeValueProvider

Acquisisce modifiche di proprietà apportate dall'utente nella finestra di progettazione e fornisce nuovi valori in fase di progettazione.

Creazione di provider di funzionalità in fase di progettazione

In molti casi, non sarà necessario creare connettori di funzionalità personalizzati. È possibile creare un provider di funzionalità e associarlo direttamente alla classe utilizzando FeatureConnectorAttribute. La classe FeatureManager è il componente di WPF Designer che attiva provider di funzionalità. FeatureManager esamina i metadati di un oggetto appena viene posizionato sull'area di progettazione. Se viene trovato FeatureConnectorAttribute per un oggetto, viene creato il provider di funzionalità associato.

Ad esempio, se si desidera creare uno strumento decorativo che consenta di modificare il testo dell'intestazione di un controllo personalizzato direttamente nella finestra di progettazione, occorre implementare lo strumento decorativo derivandolo da PrimarySelectionAdornerProvider, che a sua volta è derivato da FeatureProvider. Successivamente occorre associare lo strumento decorativo personalizzato al controllo utilizzando FeatureConnectorAttribute.

Associazione di provider di funzionalità a dei tipi

Uno strumento della fase di progettazione associa provider di funzionalità ai tipi attraverso gli attributi dei metadati. Occorre utilizzare una modalità dichiarativa per associare i metadati agli effettivi oggetti e istanze di runtime. Questa associazione è richiesta a livello dello strumento e non è responsabilità di un framework in fase di progettazione. Nell'illustrazione seguente viene mostrato come uno strumento in fase di progettazione allega i provider di funzionalità ai differenti tipi.

Associazione di provider e tipi di funzionalità

Esistono due modi per associare i provider di funzionalità ai tipi nell'architettura WPF Designer: i tipi FeatureAttribute e FeatureConnectorAttribute. Il tipo FeatureAttribute è utilizzato su tipi o istanze di oggetti modificabili ed espone una proprietà che rappresenta un FeatureProvider.

FeatureConnectorAttribute decora una classe FeatureProvider e indica quale tipo di connettore di funzionalità è necessario per ospitare il provider di funzionalità specificato. La classe FeatureManager crea le necessarie istanze FeatureConnector<TFeatureProviderType> quando vengono modificati gli oggetti passati ad essa.

Considerare una finestra di progettazione specifica di WPF nella quale gli oggetti modificabili sono di tipo UIElement. Tale strumento consente di utilizzare uno o più punti di controllo per adornare i limiti di elementi singoli. Questi strumenti decorativi rappresentano visivamente la selezione e abilitano la manipolazione di questi oggetti modificabili. La finestra di progettazione associa una funzionalità del punto di controllo a tutti gli oggetti di tipo UIElement tramite i metadati. Nell'illustrazione seguente viene mostrato come un progettatore può allegare un provider di punti di controllo a un UIElement nell'area di progettazione.

Esempio di provider di funzionalità

Se esiste un UIElement e viene passato al gestore di funzionalità per l'analisi, GrabHandleProvider viene individuato tramite i metadati associati a UIElement. Il tipo GrabHandleProvider stesso, o il tipo di base, viene ispezionato tramite i metadati per determinare il necessario connettore di funzionalità.

Connettori di funzionalità

I connettori di funzionalità sono il livello più basso di estensibilità esposto da questa architettura. I connettori di funzionalità vengono creati e viene loro assegnato un riferimento a EditingContext. I connettori di funzionalità possono sottoscrivere servizi globali e possono aggiungere i propri servizi. La classe astratta FeatureConnector<TFeatureProviderType> implementa l'interfaccia IDisposable, che promuove una semplice strategia di pulizia.

I connettori di funzionalità vengono creati su richiesta. Quando la classe FeatureManager individua FeatureConnectorAttribute in FeatureProvider, crea l'oggetto FeatureConnector<TFeatureProviderType> specificato, se non ne esiste già il tipo. I connettori di funzionalità vengono creati solo quando vengono individuati, quindi non ne viene creato un insieme predefinito all'avvio. Se esiste più di un tipo FeatureConnectorAttribute per FeatureProvider, vengono inizializzati tutti i connettori di funzionalità. In questo modo è possibile per un altro produttore derivare da un FeatureProvider esistente, aggiungere un connettore di funzionalità personalizzato e fare in modo che entrambi gli insiemi di funzionalità siano inizializzati.

La maggior parte della funzionalità della classe FeatureConnector<TFeatureProviderType> è implementata nel metodo CreateFeatureProvidersprotetto. Se viene passato un oggetto in questo metodo, il connettore di funzionalità ricerca i tipi FeatureAttribute sull'oggetto. Se questi attributi vengono trovati, viene creata l'istanza di FeatureProvider associata a ogni attributo, che viene restituita in un elenco.

La classe di base FeatureConnector<TFeatureProviderType> è generica e utilizza il tipo del provider di funzionalità ospitato da FeatureConnector<TFeatureProviderType>. I provider di funzionalità utilizzano FeatureConnectorAttribute per indicare il connettore di funzionalità associato. I metodi di classe base protetti di FeatureConnector<TFeatureProviderType>, principalmente il metodoCreateFeatureProviders, possono restituire insiemi di provider di funzionalità con tipo ai connettori di funzionalità derivati senza che ci si debba occupare di cast e sicurezza del tipo nelle classi derivate.

Creazione di connettori di funzionalità personalizzati

Occorre creare un connettore di funzionalità personalizzato quando si desidera ascoltare eventi della finestra di progettazione, quali la selezione. Derivare dalla classe FeatureConnector<TFeatureProviderType> o dalla classe PolicyDrivenFeatureConnector<TFeatureProviderType> per implementare la logica di progettazione personalizzata.

Ai connettori di funzionalità viene fornito un riferimento al EditingContext globale della finestra di progettazione tramite il quale il connettore di funzionalità può accedere a servizi della finestra di progettazione e anche pubblicare i propri servizi personalizzati. Ad esempio, un fornitore di controlli per grafici può pubblicare un servizio che consenta a un editor di tipi personalizzato nella finestra di progettazione di enumerare tutti i widget attualmente nel grafico.

Una volta creata una classe derivata da FeatureConnector<TFeatureProviderType>, è possibile associarla a un provider di funzionalità applicando FeatureConnectorAttribute al provider di funzionalità. Ogni volta che un'istanza di quel provider di funzionalità viene creata, FeatureManager esamina i metadati per FeatureConnectorAttribute. Se l'attributo è definito e un'istanza di FeatureConnector<TFeatureProviderType> associato non è attualmente in esecuzione, FeatureManager la creerà e assocerà tutte le istanze future di quel provider di funzionalità a FeatureConnector<TFeatureProviderType>.

Per un esempio di codice che illustri come implementare un connettore di funzionalità, vedere Procedura: creare un connettore di funzionalità personalizzato.

Vedere anche

Riferimenti

AdornerProvider

EditingContext

FeatureManager

FeatureConnectorAttribute

Altre risorse

Estensibilità di Progettazione WPF