Architettura di modifica dei modelli

L'implementazione in fase di progettazione interagisce con i controlli di runtime tramite un'interfaccia di programmazione denominata modello di modifica. Gli oggetti progettati sono chiamati oggetti modificabili. In questo argomento vengono descritti l'architettura e l'utilizzo del modello di modifica in WPF Designer per Visual Studio.

I controlli sono definiti nel linguaggio Extensible Application Markup Language (XAML). I controlli vengono aggiornati a livello di codice XAML utilizzando il modello di modifica.

Modello, wrapper e visualizzazione

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. Il modello e la visualizzazione sono distinti fra loro, ma il wrapper e il modello sono strettamente correlati. Nella figura seguente è illustrata la relazione tra le tre sottounità.

Relazioni Model, ModelItem e View

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.

Creazione di istanze

Qualsiasi funzionalità della finestra di progettazione che richiede la creazione di nuovi oggetti nell'area di progettazione utilizza la classe ModelFactory. Di ogni oggetto nella finestra di progettazione viene eseguito il wrapping con un'istanza ModelItem. Gli elementi del modello sono creati da un ModelFactory.

Nel codice riportato di seguito viene illustrata una tipica chiamata di ModelFactory.

ModelItem newButton = ModelFactory.CreateItem(_context, typeof(Button));

Il metodo CreateItem restituisce sempre un tipo di dati di ModelItem. Si tratta del tipo di base per tutti gli elementi nel modello di modifica di WPF Designer e rappresenta un'istanza di cui è stato eseguito il wrapping del tipo passata al metodo CreateItem. Il metodo CreateItem richiede anche un'istanza di un contesto di modifica di WPF Designer (_context nell'esempio di codice precedente), utilizzata per individuare altri servizi e altre dipendenze nella finestra di progettazione.

La creazione di elementi esplicita tramite factory è importante per oggetti da posizionare nell'area di progettazione che hanno inizializzatori predefiniti. Questa procedura non è necessaria quando si impostano semplicemente dei valori nelle proprietà.

Utilizzare sempre il metodo CreateItem per creare i nuovi oggetti nell'area di progettazione. Questa operazione è necessaria perché non è possibile analizzare molte istanze non elaborate in elementi del modello. Una volta impostato un valore nel modello, è necessario interagire con esso solo tramite il modello. L'istanza sottostante il modello può essere ricompilata in qualsiasi momento dal framework, operazione che invalida qualsiasi riferimento memorizzato nella cache.

Opzioni di creazione

Talvolta può essere necessario personalizzare il comportamento di creazione degli oggetti. Ad esempio, è possibile impostare un componente della connessione al database in modo che non esegua query al database in fase di progettazione. È possibile che si desideri avere il controllo sulla creazione di un'istanza la prima volta che un componente viene creato.

In questo caso, il componente viene trascinato dalla casella degli strumenti oppure incollato dagli Appunti. Può essere necessario preconfigurare il componente con le impostazioni predefinite utilizzabili. Queste impostazioni predefinite, se non modificate, vengono serializzate in XAML.

È possibile passare un insieme facoltativo di flag al metodo CreateItem utilizzando l'enumerazione CreateOptions.

Il flag InitializeDefaults viene utilizzato da strumenti quali lo strumento di creazione per inizializzare un insieme di valori di proprietà preconfigurati. Ad esempio, un ContentControl può fornire del contenuto predefinito. Questo metodo non sostituisce la corretta specifica dei valori predefiniti delle proprietà nel codice del controllo di runtime.

I valori impostati con questo flag restano in modo permanente in XAML.

Questo flag non deve essere utilizzato dal codice di analisi, poiché le impostazioni predefinite potrebbero essere state rimosse dall'utente durante la modifica dell'oggetto nella finestra di progettazione.

Il metodo CreateItem indirizza la chiamata CreateItem. Questo metodo esegue numerosi passaggi, come mostrato nel diagramma di flusso seguente.

Creazione di un'istanza esplicita mediante l'API di creazione

Sostituzione del padre di un elemento con un nuovo contenitore

Oltre alla creazione di nuovi elementi, un'altra attività della finestra di progettazione consiste nel sostituire il padre di un elemento con un altro. Questa attività viene gestita attraverso una classe statica denominata ModelParent, la quale fornisce funzionalità comuni alla maggior parte dei requisiti per l'assegnazione di elementi padre.

  • Individuazione dell'oggetto padre valido, dato un offset di coordinata o un elemento iniziale nella gerarchia da cercare.

  • Determinazione se un dato oggetto può essere un elemento padre di un particolare tipo.

  • Sostituzione di un elemento padre di un oggetto con un altro. Questa modifica rimuove anche il padre obsoleto dall'oggetto. Questa rimozione consente al padre obsoleto di eliminare tutti i dati, ad esempio le proprietà allegate, che risiedono nell'elemento.

La classe ModelParent funziona individuando una classe ParentAdapter per gli oggetti padre correnti e proposti. Se la classe ParentAdapter non esiste, non è possibile assegnare un oggetto a un elemento padre. La classe ParentAdapter definisce numerosi override per i casi comuni. Ad esempio, molti override accettano un oggetto GestureData come parametro. Questo tipo di dati è disponibile dal meccanismo di comando di WPF Designer quando il codice gestisce un comando dell'utente. Fornisce informazioni contestuali di uso comune.

ParentAdapter consente ai contenitori di eseguire una rimozione intelligente degli elementi padre. Ad esempio, se un oggetto con un controllo padre Canvas viene modificato in un controllo padre Grid, le proprietà allegate del controllo Canvas sull'oggetto possono essere rimosse automaticamente.

Vedere anche

Riferimenti

EditingContext

Microsoft.Windows.Design.Services

GestureData

Altre risorse

Estensibilità di Progettazione WPF