WPF with MVVM: From the Trenches
Brent EdwardsSenior Consultant with MagenicBrentE@magenic.com@brentledwardsbrentedwards.net
Why ‘From the Trenches’?
What We Will CoverWhat is MVVM?
Cool WPF concepts
What is it?
Why is it cool?
How is it used?
Helpful tricks to make life easier
Useful tools that make debugging suck less
Develop sample app as we goWhat is MVVM?
What is MVVM?ModelBusiness logicBusiness ObjectViewPresentationXAMLView ModelFunctionalityModel for the View
Why is MVVM Cool?Separates Presentation from FunctionalityPromotes testabilityWorks great with Data BindingEasy collaboration with DesignersNo code-behinds
Cost of MVVMNo built in IDE supportAll interactions must be manually wired upNew and shiny, but fragmentedLots of different frameworksLots of different opinions
Cool WPF Concepts
DataContextWhat is it?A way to give elements a scope for data bindingWhy is it cool?Makes it easy to bind controlsCan be static or dynamic
DataContextHow is it used?StaticallyOR
DataContextHow is it used?DynamicallyFrom code
Data BindingWhat is it?A way for applications to present and interact with dataWhy is it cool?Simple syntax to set up, WPF does the rest
Data BindingHow is it used?Binding syntax in XAMLTwo Way (Default Behavior)Implement INotifyPropertyChanged on view model or business object
CommandingWhat is it?A way to bind commands to a DataContextWhy is it cool?Can wire UI events to fire commands on View ModelCan pass parameters via binding
CommandingHow is it used?Expose ICommand property on View ModelAssign a command to the propertyPrism’s DelegateCommandBind to command in XAML
Commanding[Demo]
Data TemplatesWhat is it?A way to define the presentation of your dataWhy is it cool?Can give a ‘look’ to your business objectsYou can leverage data binding
Data TemplatesHow is it used?
Data Templates[Demo]
Data TriggersWhat is it?Set style properties based on data valuesWhy is it cool?Change presentation based on data properties
Data TriggersHow is it used?
Data Triggers[Demo]
Value ConvertersWhat is it?Converts data value to format required by UIWhy is it cool?Easy way to convert DateTime, Decimals, Integers or Booleans
Value ConvertersHow is it used?Implement IValueConverterConvert, ConvertBackInclude in Resources with a KeyUse it!
Value Converters[Demo]
Data Template SelectorsWhat is it?Select DataTemplate based on custom logicWhy is it coolSelect DataTemplate based on properties on view models or business objectsCan be unit tested
Data Template SelectorsHow is it used?Inherit from DataTemplateSelectorAdd properties for the DataTemplates to select fromOverride SelectTemplateAdd logic to actually select the templateAdd DataTemplates to XAML
Data Template SelectorsHow is it used?Add DataTemplateSelector to XAMLUse it!ContentControlListViewListBox
Data Template Selectors[Demo]
Helpful Tricks[To make life easier]
Event Aggregator / Message BusWhat is it?Centralized location to route [Events | Messages]Why is it cool?Great way to decouple view modelsMakes testing a breeze
Event Aggregator / Message BusHow is it used?Use an IOC containerCastle WindsorImplement as a SingletonStatic propertyImportant that all calls route through same instanceOptionsPrism’s Event AggregatorRoll your own
Event Aggregator / Message Bus[Demo]
NavigationThe ProblemViews coupled with other ViewsView Models know about ViewsNo separation of concernsNo testability
NavigationA SolutionSome Convention, Some ConfigurationLeverage [Event Aggregator | Message Bus]Leverage IOCCastle WindsorLeverage Reflection
NavigationConventionView Models all have default constructorsView Models have an optional Load method with 0 or 1 argument(s)
NavigationConfiguration – Key PlayersViewTargetsViewConfigurationViewControllerViewResultViewFactoryContainerConfiguration
NavigationConfiguration - ViewTargetsEnumerates the views which can be navigated toThe glue that sticks everything together
NavigationConfiguration - ViewConfigurationPairs a View with an optional View ModelAssociated to a ViewTarget in the IOC Container
NavigationConfiguration - ViewControllerThe only object that interacts with the UI frameworkListens for [Events | Messages] related to showing viewsGives view details to ViewFactory to be built
NavigationConfiguration – ViewFactoryResolves ViewConfiguration for the requested ViewDynamically creates the View and View ModelLoads the View Model with optional params using reflectionGives back a ViewResult
NavigationConfiguration – ViewResultResult of the dynamic build processHas the built View along with any relevant dataUsed by ViewController to show the View
Navigation[Demo]
Modal DialogsProblemModal dialogs stall tests[MessageBox| OpenFileDialog| PrintDialog]How can you leverage these and keep view models testable?
Modal DialogsOption 1Wrap them up!Define interfaceIMessageShowerDefine implementationMessageShowerWire up with IOC ContainerCastle WindsorTest with mocksRhinoMocks
Modal DialogsOption 2[Event Aggregator | Message Bus]Create [Events | Messages]Create class listen for [Events | Messages] that get publishedTest by verifying [Events | Messages] are publishedGood for “Fire and Forget”Breaks down if results are returned
Modal Dialogs[Demo]
Magic with ContentControlThe ProblemEditable View and Read Only ViewViews have identical layoutTextBox in for EditableLabel for Read Only
Magic with ContentControlA Solution – ContentControl!DataTriggersGive different presentation depending on data valuesWorks dynamicallyDataTemplateSelectorSelect which DataTemplate to useOnly works when initially bound
Magic with ContentControl[Demo]
Useful Tools[To make debugging suck less]
SnoopInspects visual treeShows propertiesShows eventsCan show 3D representation

WPF with MVVM: From the Trenches

Editor's Notes

  • #4 UI Architect for 2 WPF projects leveraging MVVM.
  • #5 This is not about WPF or MVVM. This is about WPF WITH MVVM.