Condividi tramite


Architettura di estensibilità di Progettazione WPF

Aggiornamento: novembre 2007

Progettazione Windows Presentation Foundation (WPF) per Visual Studio è un ambiente di modifica visiva per controlli WPF compositi, implementati dal°tipo UserControl. WPF Designer°è basato su un framework con un'architettura estensibile, che è possibile estendere per personalizzare l'esperienza di progettazione.

Estendendo il modello a oggetti di°WPF Designer, è possibile personalizzare in misura notevole l'aspetto e il comportamento in fase di progettazione del contenuto WPF. È ad esempio possibile estendere WPF Designer nei seguenti modi:

  • Personalizzazione dei glifi di spostamento e ridimensionamento con grafica avanzata.

  • Aggiunta nell'area di progettazione di un glifo che inclina il controllo selezionato con lo spostamento del mouse.

  • Modifica dell'aspetto e del comportamento in fase di progettazione di un controllo con strumenti diversi.

L'architettura di WPF Designer supporta appieno le funzionalità espressive avanzate di WPF, consentendo la creazione di numerose modalità di progettazione visiva che in precedenza non erano possibili.

Modello a oggetti di Progettazione WPF

Il modello a oggetti di WPF Designer è modulare, ossia°con l'estensione della fase di progettazione vengono estesi solo gli elementi necessari per le funzionalità desiderate. Non è necessario scrivere molto codice di supporto per attivare le funzionalità di progettazione personalizzate. 

Il modello a oggetti è costituito da cinque unità funzionali, descritte nella tabella seguente.

Unità funzionale

Descrizione

Modello di modifica

Interfaccia di programmazione per gli oggetti presenti nella finestra di progettazione.

Provider di funzionalità

Punto principale di estensibilità nel framework della finestra di progettazione.

Contesto di modifica

Archivio centrale per lo stato di una finestra di progettazione.

Strumenti

Strumenti per elaborare l'input dell'utente.

Archivio di metadati

Archivio contenente il comportamento in fase di progettazione di un controllo per separare fisicamente la logica delle finestre di progettazione dalla logica di runtime.

Nella figura seguente viene illustrato il modello a oggetti di WPF Designer.

Modello a oggetti ad alto livello

Nota:

WPF Designer supporta il framework di estensibilità completo. Expression Blend supporta solo editor di proprietà, caricamento di metadati e gestione licenze e non anche azioni di menu e strumenti decorativi visuali. 

Modello di modifica

L'ambiente di progettazione interagisce con i controlli di runtime tramite un'interfaccia di progettazione denominata modello di modifica. Il modello di modifica è costituito da tre sottounità funzionali: un modello, un wrapper pubblico che astrae il modello e una visualizzazione che rappresenta l'interfaccia utente del modello.

L'ambiente di progettazione comunica con il modello sottostante tramite il tipo ModelItem. Tutte le modifiche vengono apportate ai wrapper ModelItem, che influiscono sul modello sottostante. In questo modo il modello risulta semplice. I wrapper ModelItem gestiscono le funzionalità complesse della finestra di progettazione, ad esempio il supporto delle transazioni, il rilevamento degli annullamenti e le notifiche delle modifiche.

La classe ModelService fornisce il punto di ingresso per il modello di modifica e per le notifiche degli eventi globali.

La classe ViewService esegue il mapping tra le rappresentazioni visive e gli elementi del modello sottostante.

Per il funzionamento della finestra di progettazione, sono necessari entrambi i servizi. La classe DesignerView, responsabile dell'elaborazione dell'input dell'utente e del relativo routing ai comandi, richiede entrambi questi servizi per rimappare in modo accurato l'input dell'utente al modello.

Provider di funzionalità

Per estendere il comportamento in fase di progettazione dei tipi, utilizzare la classe FeatureProvider o FeatureConnector<FeatureProviderType>. La classe FeatureConnector<FeatureProviderType> gestisce un elenco di oggetti FeatureProvider.

La classe FeatureProvider fornisce il punto di estensibilità di base. Un provider di funzionalità è una funzionalità o un componente aggiuntivo leggero che in genere non richiede molto all'ambiente di progettazione e viene creato ed eliminato in un determinato contesto. I provider di funzionalità vengono utilizzati per aggiungere nuove parti dell'interfaccia utente nell'area di progettazione o per modificare un comportamento di base. Ad esempio, con un provider di funzionalità è possibile aggiungere nuovi punti di controllo o modificare il comportamento di trascinamento tramite mouse.

Per accedere al livello più avanzato di estensibilità, derivare dalla classe FeatureConnector<FeatureProviderType>. Questa classe espone un provider di servizi tramite il quale classi derivate di connettori di funzionalità possono gestire eventi e richieste e pubblicare servizi. Ad esempio, è possibile implementare un connettore di funzionalità per fornire l'interfaccia utente di selezione o la serializzazione specifica dell'oggetto.

In generale, implementare una funzionalità per estendere i concetti esistenti. Implementare un connettore di funzionalità per fornire nuovi concetti. Per ulteriori informazioni, vedere Provider di funzionalità e connettori di funzionalità.

Contesto di modifica

In una finestra di progettazione in esecuzione viene accumulata una quantità significativa di informazioni sullo stato. Ad esempio, lo stato della finestra di progettazione può indicare quali oggetti sono selezionati o il comportamento che si verifica quando viene premuto il pulsante sinistro del mouse. Poiché lo stato della finestra di progettazione è archiviato in una posizione centrale, può essere individuato quando necessario. La classe EditingContext rappresenta questo repository centrale dello stato per la finestra di progettazione.

La classe EditingContext separa lo stato in due categorie: dati e comportamento. I dati sono archiviati come tabella di elementi di contesto, mentre il comportamento come tabella di servizi. Entrambe le tabelle sono indicizzate per una chiave basata su tipo e sono enumerabili.

La classe ContextItem utilizza una singola parte dello stato nella finestra di progettazione. Gli elementi di contesto non sono modificabili, ma nuovi elementi di contesto possono sostituire quelli esistenti per simulare la modificabilità.

Ai servizi si accede tramite una proprietà Services, che restituisce un'istanza di ServiceManager, mentre agli elementi di contesto si accede tramite una proprietà Items, che restituisce un'istanza di ContextItemManager.

Comandi, attività e strumenti

L'architettura degli strumenti di WPF Designer è costituita da comandi, attività e strumenti. 

Un comando è un identificatore univoco che rappresenta alcuni comportamenti. Ad esempio, "Taglia" è un comando che indica di tagliare il testo corrente e di aggiungerlo negli Appunti. Il codice che implementa "Taglia" varia da un'applicazione all'altra e anche all'interno della stessa applicazione. Ad esempio, il taglio di testo in un documento di Word è un'implementazione diversa rispetto al taglio di testo nella casella di ricerca dello stesso documento. Indipendentemente dall'implementazione, il comando "Taglia" rimane costante.

In WPF Designer il sistema di comandi WPF è potenziato con l'introduzione del concetto di comando di strumento. Un comando di strumento implementa l'interfaccia°ICommand ed è simile alla classe RoutedCommand.

Un' attività include un insieme di associazioni di comandi che consente di aggiungere comandi indirizzati. La classe DesignerView contiene codice che utilizza la stessa strategia di routing dei comandi di strumenti per trovare ed eseguire i comandi indirizzati definiti sulle attività. La classe DesignerView abilita attività che supportano comandi WPF comuni, ad esempio Copy.

Uno strumento è una classe che elabora l'input dell'utente. Tutto l'input dell'utente viene immesso nella finestra di progettazione come uno o più eventi di input. Questi eventi di input vengono passati allo strumento correntemente attivo, che li converte in associazioni di input. Se viene restituita un'associazione di input, viene eseguito il comando all'interno dell'associazione.

Uno strumento può rappresentare la modalità globale della finestra di progettazione. Ad esempio, se l'utente seleziona componenti nell'area di progettazione, la modalità di selezione è possibile perché lo strumento attivo offre associazioni di input e comandi che gestiscono la selezione. Quando l'utente crea una nuova istanza di un controllo, diventa attivo uno strumento diverso, che offre un set diverso di comandi associati alle stesse associazioni di input.

Archivio di metadati

Nel framework di WPF Designer i metadati che definiscono il comportamento in fase di progettazione di un controllo sono inseriti in un assembly distinto, denominato archivio di metadati. In .NET Framework 3.5 l'archivio di metadati è implementato in tabelle di attributi basate su codice, con un file XML esterno che fa riferimento a codice di progettazione e un profilo. Strumenti diversi possono fornire archivi di metadati diversi con implementazioni della finestra di progettazione completamente diverse. Per questo motivo, il comportamento in fase di esecuzione è distinto da quello in fase di progettazione ed è quindi possibile rivedere la finestra di progettazione separatamente dal controllo. Per ulteriori informazioni, vedere Archivio di metadati.

Creazione di istanze della finestra di progettazione

Nei passaggi seguenti viene illustrata la creazione di istanze di un tipo di finestra di progettazione di esempio tramite l'ambiente WPF Designer. In questo esempio fittizio viene selezionato un singolo controllo pulsante nell'area di progettazione di un'ipotetica finestra di progettazione.

  1. L'utente richiama un'azione definita da strumento che richiede la creazione di una finestra di progettazione personalizzata.

  2. L'ambiente di progettazione enumera un elenco basato su XML di associazioni tra funzionalità e tipi.

  3. L'ambiente di progettazione aggiunge metadati personalizzati a questi tipi utilizzando la classe TypeDescriptor. Ad esempio, un oggetto GrabHandleProvider potrebbe essere associato a tutti i tipi UIElement, inclusi i tipi derivanti.

  4. Una factory di modifica crea un archivio di modifica, un contesto e un gestore di funzionalità, quindi popola l'archivio di modifica.

  5. In WPF Designer vengono enumerati tutti gli oggetti UIElement, che vengono esposti dall'archivio di modifica, e viene chiamato il metodo InitializeFeatures per ognuno di essi.

    1. Si presupponga che in questa gerarchia venga dichiarato un elemento Button.

    2. FeatureManager cerca un oggetto FeatureAttribute nel pulsante. FeatureManager individua un oggetto FeatureAttribute nel pulsante di tipo GrabHandleProvider.

    3. FeatureManager continua a ricercare nel tipo GrabHandleProvider e individua un oggetto FeatureConnectorAttribute associato. FeatureConnectorAttribute specifica SelectionConnector.

    4. FeatureManager determina che questo host non esiste ancora. FeatureManager crea SelectionConnector e lo aggiunge all'elenco di host di funzionalità attivi.

    5. L'oggetto SelectionConnector inizia il monitoraggio dell'area di progettazione per rilevare modifiche di selezione. L'oggetto SelectionConnector ottiene anche un riferimento al livello degli strumenti decorativi.

  6. L'utente modifica la selezione sul pulsante e lo strumento Design-Time genera un evento di selezione modificata.

  7. SelectionConnector riceve questa notifica e crea tutte le istanze di FeatureProvider basate sulla selezione associate all'oggetto selezionato, inclusa l'istanza GrabHandleProvider.

  8. SelectionConnector esegue una query su GrabHandleProvider per un elenco di strumenti decorativi e li aggiunge al livello degli strumenti decorativi. Intorno al pulsante selezionato vengono visualizzati i punti di controllo.

Assembly di Progettazione WPF

WPF Designer°comprende diversi assembly che appartengono a una delle tre categorie seguenti: assembly pubblici, privati e specifici di Visual Studio.

Gli assembly pubblici espongono classi che è possibile utilizzare per aggiungere logica della fase di progettazione ai controlli.

Gli assembly privati e specifici di Visual Studio definiscono il set di funzionalità di WPF Designer e le relative interazioni con Visual Studio. Nella tabella seguente viene illustrato come vengono distribuite le funzionalità di WPF Designer.

Assembly

API pubblica

Descrizione

Microsoft.VisualStudio.Xaml.dll

No

Logica di integrazione con Visual Studio SDK

Microsoft.Windows.Design.Host.dll

API pubblica per l'hosting della finestra di progettazione (specifica di Visual Studio)

Microsoft.Windows.Design.Developer.dll

No

Implementazione di°WPF Designer. Solo l'API pubblica è una tabella di attributi.

Microsoft.Windows.Design.Core.dll

Fornisce le basi per tutte le finestre di progettazione tramite un backplane di servizi e dati, nonché la modifica di metadati. Si tratta dell'unico assembly supportato da Expression Blend.

Microsoft.Windows.Design.Extensibility.dll

Fornisce il modello di estensibilità tramite attributi.

Microsoft.Windows.Design.Interaction.dll

Fornisce le classi di input dell'utente e visualizzazione.

Microsoft.Windows.Design.Markup.dll

Fornisce i meccanismi dei modelli di documenti e XAML (Extensible Application Markup Language).

Nota:

Gli assembly rappresentano limiti di funzionalità, non limiti di spazi dei nomi. Gli spazi dei nomi si estendono spesso in più di un assembly.

Architettura di Progettazione WPF e Progettazione Windows Form

L'architettura di WPF Designer è sostanzialmente diversa dall'architettura di Progettazione Windows Form, che è caratterizzata dall'interfaccia IComponent e dallo spazio dei nomi System.ComponentModel. Per ulteriori informazioni, vedere Confronto tra framework di Progettazione Windows Form e framework di Progettazione WPF

Vedere anche

Concetti

Provider di funzionalità e connettori di funzionalità

Altre risorse

Sviluppo di controlli Windows Form in fase di progettazione

Estensibilità di Progettazione WPF