You are previewing Pro WPF and Silverlight MVVM: Effective Application Development with Model-View-ViewModel.
O'Reilly logo
Pro WPF and Silverlight MVVM: Effective Application Development with Model-View-ViewModel

Book Description

WPF and Silverlight are unlike any other user interface (UI) technologies. They have been built to a new paradigm that—if harnessed correctly—can yield unprecedented power and performance. This book shows you how to control that power to produce clean, testable, maintainable code.

It is now recognized that any non-trivial WPF or Silverlight application needs be designed around the Model-View-ViewModel (MVVM) design pattern in order to unlock the technology's full data-binding potential.

However, the knowledge of how to do this is missing from a large part of the development community—even amongst those who work with WPF and Silverlight on a daily basis. Too often there is a reliance on programmatic interaction between controls and not enough trust in the technologies' data-binding capabilities. This leads to a clouding of design values and an inevitable loss of performance, scalability, and maintainability throughout the application.

Pro WPF and Silverlight MVVM will show you how to arrange your application so that it can grow as much as required in any direction without danger of collapse.

Table of Contents

  1. Copyright
  2. About the Author
  3. About the Technical Reviewer
  4. Acknowledgments
  5. Introduction
  6. 1. Overview of WPF and Silverlight
    1. 1.1. WPF and Silverlight
      1. 1.1.1. What Is WPF?
        1. 1.1.1.1. Architecture
        2. 1.1.1.2. DirectX, Not GDI+
        3. 1.1.1.3. Media
        4. 1.1.1.4. Layout
        5. 1.1.1.5. Styling and Templating
      2. 1.1.2. What Is Silverlight?
        1. 1.1.2.1. Architecture
        2. 1.1.2.2. .NET for Silverlight
        3. 1.1.2.3. Silverlight 4
      3. 1.1.3. Differences Between WPF and Silverlight
        1. 1.1.3.1. WPF Has 3D Graphics
        2. 1.1.3.2. WPF Targets Desktop
        3. 1.1.3.3. Silverlight Targets More Browsers
        4. 1.1.3.4. Silverlight Has Rich Online Media
        5. 1.1.3.5. WPF Has Full .NET Framework
        6. 1.1.3.6. Silverlight Runs on Macs and Linux
        7. 1.1.3.7. WPF or Silverlight?
      4. 1.1.4. Multi-Target Platforms
        1. 1.1.4.1. Separate Assemblies
        2. 1.1.4.2. Partial Classes
        3. 1.1.4.3. Extension Methods
        4. 1.1.4.4. Compiler Directives
    2. 1.2. XAML
      1. 1.2.1. Declarative User Interfaces
        1. 1.2.1.1. XAML Code-Behind
        2. 1.2.1.2. Almost Codeless
      2. 1.2.2. XAML Elements
        1. 1.2.2.1. XAML Objects
        2. 1.2.2.2. XAML Attributes
        3. 1.2.2.3. XAML Property Elements
        4. 1.2.2.4. XAML Collections
        5. 1.2.2.5. XAML Content
      3. 1.2.3. XAML Features
        1. 1.2.3.1. Markup Extensions
        2. 1.2.3.2. Type Converters
        3. 1.2.3.3. Attached Properties
        4. 1.2.3.4. Namespaces
    3. 1.3. User Experience vs. User Interface
    4. 1.4. Summary
  7. 2. DataBinding
    1. 2.1. The Power of DataBinding with XAML
      1. 2.1.1. Dependency Objects
        1. 2.1.1.1. Dependency Property Hosting
        2. 2.1.1.2. Attached Property Hosting
        3. 2.1.1.3. Dependency Property Metadata
        4. 2.1.1.4. DispatcherObject
      2. 2.1.2. Dependency Properties
        1. 2.1.2.1. XAML Integration
        2. 2.1.2.2. Databinding
        3. 2.1.2.3. Property Value Inheritance
        4. 2.1.2.4. Styling
      3. 2.1.3. Binding Sources
        1. 2.1.3.1. POCOs
        2. 2.1.3.2. Dynamic Objects
        3. 2.1.3.3. ADO.NET Objects
        4. 2.1.3.4. XML Objects
        5. 2.1.3.5. Dependency Objects and Dependency Properties
      4. 2.1.4. Binding Modes
        1. 2.1.4.1. One-Way (Readonly) Binding
        2. 2.1.4.2. Two-Way (Read/Write) Binding
        3. 2.1.4.3. One-Way-To-Source Binding
        4. 2.1.4.4. One-Time Binding
      5. 2.1.5. The DataContext
    2. 2.2. Advanced DataBinding
      1. 2.2.1. Binding Parameters
        1. 2.2.1.1. BindingGroupName
        2. 2.2.1.2. BindsDirectlyToSource
        3. 2.2.1.3. Converter and ConverterParameter
        4. 2.2.1.4. ElementName
        5. 2.2.1.5. FallbackValue
        6. 2.2.1.6. IsAsync
        7. 2.2.1.7. NotifyOnSourceUpdated and NotifyOnTargetUpdated
        8. 2.2.1.8. NotifyOnValidationError
        9. 2.2.1.9. Path
        10. 2.2.1.10. Source and RelativeSource
        11. 2.2.1.11. StringFormat
        12. 2.2.1.12. TargetNullValue
        13. 2.2.1.13. UpdateSourceExceptionFilter
        14. 2.2.1.14. UpdateSourceTrigger
        15. 2.2.1.15. Validation
        16. 2.2.1.16. XPath
      2. 2.2.2. Data Conversion
        1. 2.2.2.1. IValueConverter Interface
        2. 2.2.2.2. IMultiValueConverter Interface
      3. 2.2.3. ObjectDataProvider
        1. 2.2.3.1. Object Construction
        2. 2.2.3.2. Method Binding
        3. 2.2.3.3. Asynchronous Methods
        4. 2.2.3.4. Binding to Enumerations
      4. 2.2.4. Debugging DataBindings
        1. 2.2.4.1. Default Debug Output
        2. 2.2.4.2. TraceSources
        3. 2.2.4.3. PresentationTraceSources
        4. 2.2.4.4. Value Converter
      5. 2.2.5. Templating
        1. 2.2.5.1. The Logical and Visual Trees
        2. 2.2.5.2. ControlTemplate
        3. 2.2.5.3. DataTemplate
    3. 2.3. Summary
  8. 3. Model-View Separation
    1. 3.1. Separation of Concerns
      1. 3.1.1. Dependencies
        1. 3.1.1.1. Partitioning Dependencies with Assemblies
      2. 3.1.2. MVVM Alternatives
        1. 3.1.2.1. XAML Code Behind
        2. 3.1.2.2. Model View
    2. 3.2. The Model
      1. 3.2.1. Encapsulation
      2. 3.2.2. Don't Repeat Yourself (DRY)
      3. 3.2.3. You Ain't Gonna Need It (YAGNI)
      4. 3.2.4. The Law of Demeter
      5. 3.2.5. Test-Driven Development
        1. 3.2.5.1. Unit Tests Are Proof that Code Works
        2. 3.2.5.2. Regression Tests Are Built-In
        3. 3.2.5.3. Unit Tests Are First-Class Clients
        4. 3.2.5.4. Retrofitting Unit Tests Is Difficult
        5. 3.2.5.5. Why Many Do Not Test First
    3. 3.3. The View
      1. 3.3.1. Data Representation
      2. 3.3.2. User Input
        1. 3.3.2.1. Events
        2. 3.3.2.2. Commands
      3. 3.3.3. Data Binding
    4. 3.4. Separating Model from View
      1. 3.4.1. The Mediator Pattern
        1. 3.4.1.1. Coupling and Cohesion
      2. 3.4.2. Other Model-View-X Implementations
        1. 3.4.2.1. Model-View-Presenter
        2. 3.4.2.2. Model-View-Controller
      3. 3.4.3. You Gotta Keep 'Em Separated
    5. 3.5. Summary
  9. 4. The ViewModel
    1. 4.1. First ViewModel
      1. 4.1.1. The MVVM Template Project
        1. 4.1.1.1. The Model
        2. 4.1.1.2. The View
        3. 4.1.1.3. The ViewModel
    2. 4.2. .NET Framework Interfaces and Classes
      1. 4.2.1. Observer Pattern
      2. 4.2.2. INotifyPropertyChanged Interface
      3. 4.2.3. Observable Collections
        1. 4.2.3.1. INotifyCollectionChanged
        2. 4.2.3.2. ObservableCollection<T>
        3. 4.2.3.3. ReadOnlyObservableCollection<T>
      4. 4.2.4. CollectionViewSource
        1. 4.2.4.1. Grouping
        2. 4.2.4.2. Sorting
          1. 4.2.4.2.1. IComparable
        3. 4.2.4.3. Filtering
      5. 4.2.5. Constructing ViewModels
        1. 4.2.5.1. The Application
        2. 4.2.5.2. The Main Window
        3. 4.2.5.3. Dialogs
    3. 4.3. Handling Concurrency
      1. 4.3.1. Threading
        1. 4.3.1.1. Alleviating Bound Tasks
        2. 4.3.1.2. Increased Complexity
          1. 4.3.1.2.1. Shared Memory
          2. 4.3.1.2.2. Race Conditions
          3. 4.3.1.2.3. Deadlock
      2. 4.3.2. Threading Problems In WPF and Silverlight
        1. 4.3.2.1. Dispatcher and DispatcherObjects
      3. 4.3.3. Updating the UI
        1. 4.3.3.1. Pass Dispatcher to the ViewModel
        2. 4.3.3.2. Factor Out View Functionality
        3. 4.3.3.3. Using a Mediator
        4. 4.3.3.4. Subclassing ObservableCollection
        5. 4.3.3.5. Aspect Oriented Programming
    4. 4.4. Summary
  10. 5. Events and Commands
    1. 5.1. Events
      1. 5.1.1. Events in .NET
      2. 5.1.2. Events in WPF and Silverlight
        1. 5.1.2.1. Routing Strategies
        2. 5.1.2.2. Limitations
    2. 5.2. Commands
      1. 5.2.1. Command Pattern
        1. 5.2.1.1. ICommandSource
        2. 5.2.1.2. ICommand Interface
        3. 5.2.1.3. Routed Command Implementations
      2. 5.2.2. The RelayCommand
        1. 5.2.2.1. Requirements
        2. 5.2.2.2. Technical Design
        3. 5.2.2.3. Implementation
        4. 5.2.2.4. Usage
      3. 5.2.3. Attached Command Behavior
      4. 5.2.4. Avoiding Events Using Dependency Injection
    3. 5.3. Summary
  11. 6. Validation
    1. 6.1. The Validation Process
    2. 6.2. Binding Validation Rules
      1. 6.2.1. ValidationRule Class
        1. 6.2.1.1. Validate Method
        2. 6.2.1.2. Constructors
      2. 6.2.2. Exceptions for Validation
        1. 6.2.2.1. Filtering Validation Exceptions
        2. 6.2.2.2. Exceptions Represent Exceptional Circumstances
      3. 6.2.3. A Validation Framework
      4. 6.2.4. IDataErrorInfo Interface
        1. 6.2.4.1. Model Implementation
        2. 6.2.4.2. ViewModel Implementation
      5. 6.2.5. DataErrorValidationRule Class
    3. 6.3. Validation in Silverlight
    4. 6.4. Visually Formatting Validation Errors
      1. 6.4.1. Validation.ErrorTemplate Attached Property
      2. 6.4.2. Validation.HasError Attached Property
    5. 6.5. Summary
  12. 7. Unit Testing
    1. 7.1. The Importance of Testing
      1. 7.1.1. Traditional Testing
        1. 7.1.1.1. The Waterfall Methodology
        2. 7.1.1.2. The Testing Afterthought
        3. 7.1.1.3. Gaining Agility
      2. 7.1.2. What Is Unit Testing?
        1. 7.1.2.1. Defining Interface Before Implementation
        2. 7.1.2.2. Automation
        3. 7.1.2.3. Code Coverage
      3. 7.1.3. Why Unit Test?
        1. 7.1.3.1. Spread the Effort
        2. 7.1.3.2. Enforce Better Design
    2. 7.2. How to Unit Test
      1. 7.2.1. Unit Testing with Visual Studio 2010
        1. 7.2.1.1. Test Projects
        2. 7.2.1.2. NUnit
        3. 7.2.1.3. RhinoMocks
        4. 7.2.1.4. NCover
        5. 7.2.1.5. NBehave
      2. 7.2.2. Writing Tests
        1. 7.2.2.1. Assertions
        2. 7.2.2.2. Handling Exceptions
        3. 7.2.2.3. AAA: Arrange, Act, Assert
        4. 7.2.2.4. Public Methods Only
    3. 7.3. Summary
  13. 8. Data Access Layer
    1. 8.1. Object-Relational Dichotomy
      1. 8.1.1.
        1. 8.1.1.1. Mapping Object Relationships
        2. 8.1.1.2. Mapping Class Hierarchies
          1. 8.1.1.2.1. Table-Per-Class-Hierarchy
          2. 8.1.1.2.2. Table-Per-Concrete-Class
          3. 8.1.1.2.3. Table-Per-Class
    2. 8.2. DAL Implementations
      1. 8.2.1. Manual Implementation
      2. 8.2.2. Third-Party Implementations
        1. 8.2.2.1. LINQ to SQL
        2. 8.2.2.2. Entity Framework
        3. 8.2.2.3. NHibernate
    3. 8.3. Supporting Patterns
      1. 8.3.1. The Repository Pattern
        1. 8.3.1.1. Collaboration
      2. 8.3.2. Unit of Work
        1. 8.3.2.1. Collaboration
    4. 8.4. Creating the Data Schema
      1. 8.4.1. Generate, Not Create
    5. 8.5. Summary
  14. 9. Application Support
    1. 9.1. Serialization
      1. 9.1.1. Serializing POCOs
        1. 9.1.1.1. Invasive Serialization
        2. 9.1.1.2. External Serialization
    2. 9.2. Extensibility
      1. 9.2.1. Why Extend?
        1. 9.2.1.1. Natural Team Boundaries
        2. 9.2.1.2. Community
      2. 9.2.2. Using Managed Extensibility Framework
        1. 9.2.2.1. Import
          1. 9.2.2.1.1. AllowDefault
          2. 9.2.2.1.2. AllowRecomposition
          3. 9.2.2.1.3. ContractName
          4. 9.2.2.1.4. ContractType
          5. 9.2.2.1.5. IPartImportsSatisfiedNotification Interface
        2. 9.2.2.2. Export
        3. 9.2.2.3. Catalogs
          1. 9.2.2.3.1. TypeCatalog
          2. 9.2.2.3.2. AssemblyCatalog
          3. 9.2.2.3.3. DirectoryCatalog
          4. 9.2.2.3.4. AggregateCatalog
        4. 9.2.2.4. Container
      3. 9.2.3. Extending A WPF Application
        1. 9.2.3.1. Defining An Extension Contract
        2. 9.2.3.2. Sharing User Interface Components
        3. 9.2.3.3. Attaching a DataTemplate
      4. 9.2.4. Limitations
        1. 9.2.4.1. Decorating POCOs
        2. 9.2.4.2. Single Process, Single AppDomain
    3. 9.3. Summary
  15. 10. Sample Application
    1. 10.1. Requirements
      1. 10.1.1. The Application
    2. 10.2. Model and Tests
      1. 10.2.1. Money
      2. 10.2.2. Account
    3. 10.3. ViewModel and Tests
      1. 10.3.1. MainWindowViewModel
        1. 10.3.1.1. Testing Behavior
        2. 10.3.1.2. Hiding All Model Contents
    4. 10.4. View
    5. 10.5. Summary