Questa è la parte più difficile se fai il MVVM fai-da-te.
le opzioni, fondamentalmente:
Usa Dependency Injection
Si potrebbe iniettare il ViewModel nel costruttore 's Page
/Window
e assegnarlo al suo interno.
Questo ha però qualche svantaggio.
- più difficile da usare visualizzare i modelli in fase di progettazione
- Visualizzazioni non possono essere istanziati da XAML più
ViewModel Prima con Service
Farebbe risolvere i vostri ViewModels e navigazione fai tutta la tua navigazione tramite un servizio di navigazione. Nel tuo ViewModels si passa il INavigationService
. È possibile navigare verso una vista usando il tipo ViewModel. Al suo interno istanziare ViewModel tramite Dipendenza Iniezione, quindi istanziare la Vista (basata su convenzioni di denominazione o tramite configurazione DI)
Questo è un po 'meglio, ma ancora non ti permetterà di istanziare le Viste in XAML. Un grande vantaggio è che permette facilmente di passare parametri al ViewModel (avendo i ViewModels implementano INavigationAware
proprietà con NavigatedTo
metodo, che è chiamato dopo l'istanza e passando il parametro a)
ViewModelLocator/Attached Property/Comportamento
Con questo, crei una proprietà associata, che puoi impostare su true
(ad esempio, autowire) o su un tipo ViewModel (per avere più controllo sul ViewModel istanziato) e trovare e risolvere ViewModel e assegnarlo.
Fondamentalmente offre tutti i vantaggi sopra più la forma di istanziazione Vista.
L'ultimo che è fondamentalmente ciò che MVVM framework di Microsoft "Prism" fa (servizio di navigazione navigationService.Navigate("MyPage", myParameterForViewModel)
, DataContext esemplificazione e l'assegnazione da XAML via autowireing (in XAML:. prism:ViewModelLocator.AutoWireViewModel="True"
)
Detto questo, è meglio utilizzare un stagionato MVVM quadro che fa questo parti del cablaggio (anche se si decide di non utilizzare le classi di base, come BindableBase
o come si chiama in tale quadro)
per quanto riguarda la fase di progettazione ViewModel/auto-completition per ViewModel:.
È possibile utilizzare gli attributi Design-Time di Blend per fare ciò. È necessario aggiungere prima i riferimenti all'assieme Blend. Quindi puoi aggiungere lo spazio dei nomi xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
nella tua pagina/vista.
Quindi è possibile associarlo alla pagina tramite d:DataContext="{d:DesignInstance my:DesignTimeViewModel, IsDesignTimeCreatable=True}
. Notare d:
prima di DataContext, questo è importante. Questo DataContext verrà utilizzato solo nella finestra di progettazione (Visual Studio XAML Designer o in Blend). Questo per evitare di interferire con il normale DataContext
(senza il prefisso).
Esempio:
<Window x:Class="WpfApplication1.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:myApp="clr-namespace:WpfApplication1"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance myApp:Window2ViewModel, IsDesignTimeCreatable=True}">
<Grid>
<TextBlock Text ="{Binding Test}"/>
</Grid>
</Window>
Se si utilizza interfacce per i vostri ViewModels, è abbastanza veloce per creare il design istanza, semplicemente avendo Visual Studio implementare tutte le proprietà di interfaccia e dare alcuni valori di default (per la proprietà in modo hai dati di esempio nel tuo ViewModel per verificare che i collegamenti funzionino correttamente).
Ciò richiede di creare ViewModels separati in fase di progettazione e ViewModels effettivi, che non è così male come sembra. Questo dà al tuo designer dell'interfaccia utente la possibilità di lavorare con esso, anche se il vero ViewModel non è ancora stato completato/implementato.
Tseng, Grazie per la risposta. Con l'opzione "Use Dependency Injection" non ci sarà il controllo del binding in fase di progettazione, cioè nell'editor XAML otterrò l'avviso "Impossibile risolvere il simbolo XXX a causa di DataContext sconosciuto". Inoltre, non potrò fare clic sul nome di una proprietà all'interno di "{Binding PropertyName}" e saltare automaticamente su una dichiarazione di proprietà. – WpfNewbie
Tseng, ho aggiunto un esempio (con estensione markup DesignInstance) nella tua risposta. Qualcuno lo approvi (non ho ancora abbastanza "potere"). Inoltre, non ho dovuto fare riferimento all'assemblaggio di Blend e ho dovuto aggiungere mc: Ignorable = "d" per renderlo compilabile. – WpfNewbie
L'estensione di markup DesignInstance risolve il mio problema. Grazie. Contrassegnato come risposta. – WpfNewbie