Diese Präsentation wurde erfolgreich gemeldet.
Wir verwenden Ihre LinkedIn Profilangaben und Informationen zu Ihren Aktivitäten, um Anzeigen zu personalisieren und Ihnen relevantere Inhalte anzuzeigen. Sie können Ihre Anzeigeneinstellungen jederzeit ändern.

Adopting MVVM

3.744 Aufrufe

Veröffentlicht am

AN introduction to MVVM

Veröffentlicht in: Technologie
  • Als Erste(r) kommentieren

Adopting MVVM

  1. 1. ADOPTING MVVM John Cumming Senior Engineer – CM Group Ltd http://www.cmgroup.co.uk http://sputnikdev.wordpress.com
  2. 2. Overview • A bit about my experience of MVVM. • What problems adopting MVVM addresses. • An overview of the MVVM pattern. • Adopting MVVM. • A simple example.
  3. 3. About me …
  4. 4. PROBLEMS MVVM ADDRESSES
  5. 5. Typical Development Problems • Tightly coupled brittle code that is difficult to maintain and extend. • It can be difficult to separate UI state and logic from the UI presentation. • Difficult to test UI state and logic. • The designer is tied to the UI components written by the developer.
  6. 6. MVVM … • Tightly coupled brittle code that is difficult to maintain and extend. • It can be difficult to separate UI state and logic from the UI presentation. • Difficult to test UI state and logic. • The designer is tied to the UI components written by the developer.
  7. 7. Separation of Concerns • View – UI Layout & User Interaction • View Model – UI State and Logic • Model – Business Logic and Data
  8. 8. Natural XAML Pattern • Data Binding – DataContext • Data Binding – Dependency Properties • Commands – Executing Actions & Operations
  9. 9. Increased Testability • UI State & Logic independent of UI technology.
  10. 10. Developer Designer Workflow • Designer has freedom to design. • Designer can work independently. • Designer does not need to touch code. • Designer can create design time sample data.
  11. 11. MVVM OVERVIEW
  12. 12. MVVM View • The View defines the structure and appearance of the UI. • The View’s DataContext is a View Model. • Minimal, if any, code behind. • View updated by notification events from the View Model. • UI Gestures are passed to the View Model, usually via Commands.
  13. 13. MVVM View Model • The View Model is responsible for UI logic, data and state. • The View Model exposes bindable properties. • The View Model exposes ICommand properties for UI controls with Command properties. • The View Model exposes public methods that can be invoked by the View. • The View Model is completely testable.
  14. 14. MVVM Model • The Model is responsible for business logic and data, the client side Domain Model. • The Model can expose bindable properties for use by the View directly or via the View Model as an Adapter. • Model objects can implement IDataErrorInfo to provide the View with validation state information.
  15. 15. MVVM Commands • Invoked in the View by user interaction. • Bound to ICommand properties in the View Model. • Differ from WPF Routed Commands as they are not delivered via the UI logical tree. Equally, Routed Commands will not get delivered to the View Model as it is outside the UI logical tree.
  16. 16. Data Validation / Error Reporting • Implement IDataErrorInfo or INotifyDataErrorInfo in View Model and Model classes. • IDataErrorInfo – presents basic indexed error information. • INotifyDataErrorInfo – presents multiple errors per property, asynchronous data validation and notification of error state changes (In WPF 4/ Silverlight 4).
  17. 17. ADOPTING MVVM
  18. 18. A Typical MVVM Application Order of Construction Dependency Injection Param-less Contructors D:DataContext d:DesignSource Objects or Methods IDateErrorInfo INotifyDataErrorInfo
  19. 19. Construction and Wire Up • One-to-One loosely coupled relationship between View and View Model. • Create View as a Data Template. – The View Model is instantiated first. – Data Templates are lightweight and flexible. – No code behind is available for Data Templates.
  20. 20. Construction and Wire Up • Create the View Model in the View’s XAML. – Requires a parameterless ctor in the View Model. – Works well in design tools. – The View must have knowledge of the View Model type. • Instantiate the View Model in the View’s code behind. – The View must have knowledge of the View Model type. – Loose coupling can be achieved by use of a dependency injection container such as Unity.
  21. 21. Provision of Design Time Data • Expression Blend XML Sample Data. – Simple to create in Blend. – Not rendered in Visual Studio. – Sample data not compiled in, but schema is. • XAML Sample Data. – Uses d:DesignData XAML markup extension. – Supported in Blend 4 and VS2010. – XAML sample data is not compiled into assemblies.
  22. 22. Provision of Design Time Data • XAML Resource. – Provide a simple resource instantiating desired types. – Useful for quick throw away data when editing a template. • Code. – Uses d:DataContext and d:DesignInstance XAML markup extensions. – May need to be maintained by developers.
  23. 23. Key Decisions • Construct Views or View Models first and use of a dependency injection container. • Expose Commands from the View Model as Command objects or Command methods. • Use of IDataErrorInfo / INotifyDataErrorInfo. • Provision of design time data for use in Expression Blend.
  24. 24. AN MVVM EXAMPLE
  25. 25. In the Box – MVVM Training http://karlshifflett.wordpress.com/2010/11/07/in-the-box-ndash-mvvm-training/
  26. 26. Basic WPF Application
  27. 27. Pre MVVM private void MediaList_MouseDoubleClick( object sender, MouseButtonEventArgs e) { MediaFile mediaFile = MediaList.SelectedItem as MediaFile; if (mediaFile != null) { _mediaFolder.Play(mediaFile); CurrentItem.DataContext = mediaFile; } } UI Interactions implemented as code behind <Application x:Class="WpfMediaPlayer.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" StartupUri="MainWindow.xaml"> Bootstrapping – StartupUri for App _mediaFolder.Load(this.MediaFolderPath.Text); this.MediaList.ItemsSource = _mediaFolder.MediaFiles; UI Binding to MediaFile Properties
  28. 28. Pre MVVM - Comments • Low Concept Count…. It is a simple app after all! • Minimal code required for implementation. • Testability - All UI logic and state is implemented as code behind and is difficult to test. • Coupling - The MainWindow class needs knowledge of the data types. • Extensibility / Maintainability – Code rapidly becomes complex and potentially confusing as new UI features are added.
  29. 29. MVVM Separate View Components in UI Bootstrapping – Dependency Injection Implement View Models Decouple View Models and Model Bindable Properties Command Properties
  30. 30. MVVM View Components <<View>> SelectedDirectoryView <<View>> MediaListView <<View>> NowPlayingView
  31. 31. MVVM View Components <Grid VerticalAlignment="Stretch" Margin="5"> <Grid.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="Views/MediaListView.xaml"/> <ResourceDictionary Source="Views/NowPlayingView.xaml"/> <ResourceDictionary Source="Views/SelectedDirectoryView.xaml"/> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Grid.Resources> <Grid.RowDefinitions> … </Grid.RowDefinitions> <ContentControl x:Name="SelectedDirectoryView" Grid.Row="0" Content="{Binding}" ContentTemplate="{StaticResource SelectedDirectoryViewTemplate}"/> <ContentControl x:Name="MediaListView" Grid.Row="1" Content="{Binding}" ContentTemplate="{StaticResource MediaListViewTemplate}"/> <ContentControl x:Name="NowPlayingView" Grid.Row="2" Content="{Binding}" ContentTemplate="{StaticResource NowPlayingViewTemplate}"/> </Grid> </Window> MainWindow.xaml
  32. 32. MVVM View Components <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:vm="clr-namespace:WpfMediaPlayer.ViewModels"> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="..Styles.xaml"/> </ResourceDictionary.MergedDictionaries> <DataTemplate x:Key="SelectedDirectoryViewTemplate" DataType="{x:Type vm:ISelectedDirectoryViewModel}" > <!-- File Picker --> <Grid Grid.Row="0" HorizontalAlignment="Stretch" Margin="0,0,0,5"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBox Grid.Column="0" IsReadOnly="True" IsEnabled="False" Text="{Binding DirectoryPath, Mode=OneWay}"/> <Button Grid.Column="1" Margin="5,0,0,0" Command="{Binding OpenCommand}"> Select Directory </Button> </Grid> </DataTemplate> </ResourceDictionary> SelectedDirectoryView.xaml
  33. 33. MVVM View Components • A little excessive for a small app? • Extensible – We can easily extend the individual Views if we wish without affecting the other views. • Implement Views as Data templates
  34. 34. MVVM View Model Components <<View>> SelectedDirectoryView <<View>> MediaListView <<View>> NowPlayingView <<ViewModel>> IMediaListViewModel <<ViewModel>> ISelectedDirectoryViewModel Commands: + ICommand PlayCommand Properties: + ObsCol<IMediaFile> MediaFiles Commands: + ICommand OpenCommand Properties: + String DirectoryPath <<ViewModel>> INowPlayingViewModel Commands: + ICommand PauseResumeCommand Properties: + …
  35. 35. MVVM View Model Components interface ISelectedDirectoryViewModel : INotifyPropertyChanged { String DirectoryPath { get; } ICommand OpenCommand { get; } } ISelectedDirectoryViewModel.cs
  36. 36. MVVM View Model Components • Decoupling UI actions using Commands. • NowPlayingViewModel provides an adapter for the IMediaFile. • Other Views bind directly to IMediaFile. • UI behaviour is now completely testable as there is no code behind any of the Views.
  37. 37. Model Components <<View>> SelectedDirectoryView <<View>> MediaListView <<View>> NowPlayingView <<ViewModel>> IMediaListViewModel <<ViewModel>> ISelectedDirectoryViewModel Commands: + ICommand PlayCommand Properties: + ObsCol<IMediaFile> MediaFiles Commands: + ICommand OpenCommand Properties: + String DirectoryPath <<ViewModel>> INowPlayingViewModel Commands: + ICommand PauseResumeCommand Properties: + … <<Model>> MediaPlayerMediaFolderMediaFile IMediaFile IMediaFolder
  38. 38. MVVM Bootstrapping protected override void OnStartup(StartupEventArgs e) { using (IUnityContainer container = new UnityContainer()) { // register models container.RegisterType<IMediaFolder, MediaFolder> (new ContainerControlledLifetimeManager()); // register view models container.RegisterType<ISelectedDirectoryViewModel, SelectedDirectoryViewModel> (new ContainerControlledLifetimeManager()); container.RegisterType<IMediaListViewModel, MediaListViewModel> (new ContainerControlledLifetimeManager()); container.RegisterType<INowPlayingViewModel, NowPlayingViewModel> (new ContainerControlledLifetimeManager()); MainWindow window = container.Resolve<MainWindow>(); window.SelectedDirectoryView.DataContext = container.Resolve<ISelectedDirectoryViewModel>(); window.MediaListView.DataContext = container.Resolve<IMediaListViewModel>(); window.NowPlayingView.DataContext = container.Resolve<INowPlayingViewModel>(); window.Show(); } } App.xaml.cs
  39. 39. MVVM - Comments • Testability – UI Logic and state is independent of UI layout. • The layers have been successfully decoupled to assist in independent testing and development of components. • The code is potentially simpler to extend into a larger application and will be simpler to maintain. • High Concept Count, especially for a simple app.
  40. 40. Summary • The MVVM pattern is well suited for WPF / Silverlight development. • Adopting MVVM can improve maintainability. • Adopting MVVM can improve quality. • Adopting MVVM frees up designer creativity. • Adopting MVVM can improve the product.
  41. 41. Questions…

×