Overview of MVVM Ivan Krivyakov Senior Managing Consultant SunGard Consulting Services E-mail: Ivan.Krivyakov@SunGard.com ivan@ikriv.com http://www.ikriv.com/demo/mvvm/ Overview of MVVM What Is This Presentation About “Traditional” WPF Programming MVVM Defined Show me the code! MVVM Problems MVVM Resources MVVM and Other MV* Patterns Overview of MVVM “Traditional” WPF Programming Overview of MVVM Traditional WPF View Architecture View XAML Model (domain objects) (UI layout) updates, may observe Code Behind Overview of MVVM XAML: window layout + named controls <StackPanel> <TextBox x:Name=“City” /> <ComboBox x:Name=“CountryList” SelectionChanged=… /> </StackPanel> Code behind: event handlers and manipulating the controls void CountryList_SelectionChanged(…) { City.Text = GetCity(CountryList.SelectedItem as Country); } Overview of MVVM Pros and Cons of the Traditional Model: •Simplicity •Power: manipulate controls as you please •Difficult to Test •Cannot easily identify modifiable UI state •Encourages using UI as data storage •Encourages mixing business logic and control manipulation Overview of MVVM What is MVVM Overview of MVVM • Model does not know anything about the UI • View is a UI element (e.g. a Window) • “Something” somehow fills the gap View Model Something Controller? Presenter? Code Behind? Overview of MVVM Model-View-ViewModel Model View (domain objects) (input, output) updates, may observe WPF Data Binding ViewModel (UI state) View.DataContext = ViewModel; http://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx Overview of MVVM Separation of Concerns Model View ViewModel Read list of countries from the database Position UI elements on screen Validate input and show error indicators if necessary Create shipment Control visual appearance of the UI elements: colors, fonts, etc. Call model to create shipment with data entered by the user Translate keystrokes to navigation and edit actions Disable subdivision combo box if selected country has no subdivisions Translate mouse clicks to focus changes and button commands Overview of MVVM Important MVVM Traits View is isolated from the model ViewModel does not manipulate controls directly Most of the View ViewModel interaction is via data binding Codebehind is therefore kept to a minimum Overview of MVVM WPF Data Binding <TextBox Text=“{Binding City}” /> class MainWindowViewModel { public string City { get { … } set { … } } … } binding Overview of MVVM Dependency Properties Richer functionality than C# properties <TextBlock Text=“Boo!” Grid.Row=“2” /> DependencyProperty DependencyObject Map: DependencyProperty à object GetValue(prop) SetValue(prop, value) Name PropertyType OwnerType ChangeCallback ValidationCallback DefaultValue <<animation support>> <<static> Register() <<static>> RegisterAttached() Overview of MVVM WPF Data Binding Continued <SomeClass Target=“{Binding Source}” /> Source Target PropertyChanged event (optional) CLR Property Dependency Property CLR Field Dependency Property Dependency Property CLR Property CLR Field Overview of MVVM WPF Data Binding Continued Target may be chosen in a number of ways Each control has a DataContext {Binding Prop}, {Binding Prop.SubProp} {Binding Prop, Converter=x} {Binding Prop, ElementName=x} {Binding Prop, RelativeSource=…} Overview of MVVM Show Me the Code! Overview of MVVM Model Country Subdivision Countries MainWindowViewModel Model Country CountryError … MainWindow Window DataContext … UI elements ... Shipment Overview of MVVM Bindings Map Model.Countries Country City Country.SubdivisionName Country.Subdivisions Subdivision CountryError CityError SubdivisionError HasSubdivisions ShipmentCost ShipCommand Shipments Overview of MVVM WPF Data Binding: Commands <Button Command=“{Binding ShipCommand}” /> class MainWindowViewModel { public ICommand ShipCommand { get { … } } … } Overview of MVVM WPF Data Binding: Commands <<interface>> ICommand Execute() CanExecute() Works with view, not suitable for MVVM RoutedCommand CommandBinding Delegate on the view Not part of .NET framework DelegateCommand Or RelayCommand Delegate on viewmodel Overview of MVVM Attached Behaviors <TextBox TextBoxExt.SelectAllOnFocus=“true” /> class TextBoxExt { DependencyProperty SelectAllOnFocusProperty = DependencyProperty.RegisterAttached( “SelectAllOnFocus”…); static void OnFocusChanged(…) { … textBox.SelectAll(); } } Overview of MVVM Unit Tests Can test Model in isolation Can test ViewModel in isolation Cannot unit test data bindings! May require use of mocking libraries to test ViewModel-to-Model and ViewModel-toView interactions Overview of MVVM MVVM Problems Overview of MVVM Problems in a Nutshell Data binding may be difficult to debug Data binding may cause performance issues Command binding requires custom components Any direct manipulation of controls must be carefully isolated Overview of MVVM How to Tell View to Do Something Use attached behaviors Have the view listen to events on ViewModel Let ViewModel call the View via an interface Use custom binding extensions, etc. Overview of MVVM Example: Setting Focus Setting focus via data binding (“pure MVVM”) requires many custom moving parts http://joshsmithonwpf.wordpress.com/2010/03/16/ control-input-focus-from-viewmodel-objects/ IFocusMover FocusBinding BindingDecoratorBase Overview of MVVM Easier way out: have view model call an interface Model View (domain objects) (input, output) WPF Data Binding updates, may observe implements ViewModel (UI state) Calls methods IView (interface) Overview of MVVM Shipment Demo implementation: MainWindow Model DataContext MainWindowViewModel Window FocusManager Focus(child:string) <<interface>> IFocusManager Focus(child:string) Overview of MVVM MVVM Resources Overview of MVVM Level of Support from Microsoft MVVM not in .NET framework No MVVM templates in Visual Studio No support classes like DelegateCommand No standard attached behaviors Proliferation of third party MVVM toolkits Overview of MVVM MVVM Toolkits contain one or more of DelegateCommand/RelayCommand MVVM templates for Visual Studio Some converters Some attached behaviors Samples and documentation Many were not updated for VS 2010 Some are primarily focused on other things: Composite UI, Event brokers, … Overview of MVVM MVVM Toolkits See Wikipedia article on MVVM MVVM Light Toolkit Prism (a Composite UI framework) Structured MVVM AttachedCommandBehavior 2.0 Overview of MVVM MVVM Books There are not that many “Advanced MVVM” by Josh Smith. Short overview on 54 pages, most of which are code annotation for BubbleBurst sample from Codeplex. “Pro WPF and Silverlight MVVM” by Gary Hall – not published yet, on pre-order Overview of MVVM Other MVVM Resources Just Google it. Enough people work on it. Stack Overflow WPF Disciples Google group Any other WPF forum Overview of MVVM Summary MVVM is a powerful concept There are some areas where solutions exist, but are by no means obvious There is no standard tool set, and even no standard terminology. Thus, you will have to assemble your tool belt yourself Fortunately, not that much is required Overview of MVVM MVVM and Other MV* Patterns Overview of MVVM 1979: Model View Controller I've lost count of the times I've seen something described as MVC which turned out to be nothing like it. Martin Fowler Model observes (domain objects) View (output) changes may update Controller (input) http://martinfowler.com/eaaDev/uiArchs.html Overview of MVVM 2004: Model View Presenter (a.k.a. supervising controller) Model observes (domain objects) updates, may observe View (input, output) observes, may update Presenter (complex presentation logic) “Let the view handle as much as possible and only step in when there's more complex logic involved.” http://martinfowler.com/eaaDev/SupervisingPresenter.html Overview of MVVM 2004?: Passive View Model Passive View (domain objects) (input, output) updates, may observe observes, updates Presenter (all presentation logic) http://martinfowler.com/eaaDev/PassiveScreen.html Overview of MVVM 2004?: Presentation Model Model View (domain objects) (input, output) updates, may observe synchronizes state with Presentation Model (UI state) Presentation model contains all variable UI state in a UI-agnostic manner The most annoying part of Presentation Model is the synchronization. Ideally some kind of framework could handle this... like .NET's data binding. http://martinfowler.com/eaaDev/PresentationModel.html