get the slides here - Bryan`s Coding Corner

advertisement
or How I Learned to Stop Worrying and Love the Binding
Bryan Anderson
 Consultant for ILM
 Worked with WPF & Silverlight for the past 2 years
 In industry for 4 ½ years
 Programming for 14 years
 Of all of the features to come to .NET 4.0, Code
Contracts are the most important
 Vocabulary & relevant Design Patterns
 Presentation Model pattern
 MVVM Architecture
 Compare MVVM to MVC
 Religious fights you’ll encounter when implementing
MVVM
 Common issues you’ll run into with MVVM and their
solutions
//Notifies clients that a property value has changed.
public interface INotifyPropertyChanged
{
//Occurs when a property value changes.
event PropertyChangedEventHandler PropertyChanged;
}
//Notifies listeners of dynamic changes, such as when items get
//added and removed or the whole list is refreshed.
public interface INotifyCollectionChanged
{
//Occurs when the collection changes.
event NotifyCollectionChangedEventHandler CollectionChanged;
}
//Describes the action that caused a CollectionChanged event.
public enum NotifyCollectionChangedAction
{
Add, Remove, Replace, Move, Reset
}
 Keeps data in two properties “bound” together
 Allows data to flow in either or both directions
 Uses PropertyChanged & CollectionChanged to keep
values updated
 Implements IValueConverter or IMultiValueConverter
 object Convert(object value, Type targetType, object
parameter, CultureInfo culture)
 object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
 Converts inputs from one value to another and back
 Used extensively in data binding
 Looks like a standard CLR property on the class’s
interface
 Adds additional infrastructure features like
 Data Binding
 Change Notification
 Value Coercion
 Used extensively by WPF and Silverlight to create fast,
reactive user interfaces
 Groups a related set of controls
 Reduces repetition – DRYer
 Has its own code behind – allows new dependency
properties
 An implementation of the Command Pattern
 In WPF & Silverlight the ICommand interface is used
to define a class that represents a command
 bool CanExecute(object parameter)
 void Execute(object parameter)
 event EventHandler CanExecuteChanged
 Frequently implemented by creating a
DelegateCommand class
Design patterns give programmers a proven solution to a
given problem with known benefits, drawbacks, and a
shared vocabulary.
 Command – Encapsulates method calls
 Mediator - Encapsulates messages between objects
 Adapter – Translates one interface into another
 Façade – Simplifies a larger interface
 Singleton - Restricts a class to a single instance
 Factory – Encapsulates the creation of an object
 Etc.
http://xkcd.com/387/
Architectural patterns serve the same purpose as other
design patterns, but they focus on the whole application
or a very large portion of it.
 Guide the separation of concerns
 Encapsulate what changes
 UI
 Web services
 Databases
 Anything else that interfaces with something outside the
application
 Separate presentation from functionality
 Testability
 Consistency
 Maintainability
 Allow a combined Blend/Visual Studio workflow
 Abstract Pattern that
View
Presentation Model
defines a family of
platform/framework
specific patterns
 MVVM – WPF, Silverlight
 MVC – Web
 MVP – Winforms
Model
 Designed to pull the state and
behavior out of the View into
a more stable and testable
layer
 Abstract Pattern that
View
Presentation Model
defines a family of
platform/framework
specific patterns
 MVVM – WPF, Silverlight
 MVC – Web
 MVP – Winforms
Model
 Designed to pull the state and
behavior out of the View into
a more stable and testable
layer
 Responsible for business
Unit Tests
View
View Model
Model
Database
Web
Services
File
System
logic
 Interacts with persistent
storage, e.g. database,
web services, files, etc.
 Capable of being shared
among related
applications
 Should be thought of as
Unit Tests
View
View Model
Model
Database
Web
Services
File
System
an Abstract View
 Exposes properties and
commands for use in a
View
 Gets data from the
Model and updates it
according to property
changes and command
calls
 Presents data to the user
Unit Tests
View
 Handles input
 Interacts with the View
View Model
Model
Database
Web
Services
File
System
Model by data binding to
properties and
commands
 Should contain no logic
that isn’t entirely a view
concern, e.g. which
screen to show
 Acts as another View
Unit Tests
View
View Model
Model
Database
Web
Services
File
System
 Interacts with the Model
and View Model to
ensure correct behavior
 Provide an early warning
that the architecture isn’t
correct
 If testing is difficult,
coupling is too high or
concerns aren’t separated
 The Model holds data and
Controller
View
Model
handles business logic
 The Controller receives input
and makes changes to the
View and Model accordingly
 The View renders the Model
into a form suitable for
interaction
 Multiple, mutually exclusive options
 People form strong opinions and will argue the
benefits of their choice for all eternity
 Each side has its own benefits and drawbacks
 A decision needs to be made before the “correct
choice” can be determined
 In the end it comes down to a combination of reason
and instinct
View Driven
 Easy to track which View
Model is used by a View
 Much easier to use when
sharing code between
WPF and Silverlight
 Difficult or confusing for
a single View to be used
with multiple View
Models
View Model Driven
 Allows more complete
testing of logic to open
new Views/View Models
 Tends to be DRYer as
applications grow
 More difficult to use in
Silverlight projects
How much code should I actually have in the View’s
code behind?
 Value converters are fine as long as they’re only
converting values
 User Control code behind should only contain
Dependency Property definitions and rare viewspecific event handlers
 DataTemplateSelectors as long as their code is limited
to choosing between DataTemplates
 Otherwise there should be no code-behind
Should the View be allowed to use/display a Model class
directly or should all interactions be through the View
Model?
 The View should never edit a Model instance
 My rule of thumb – Only allow the view to display
immutable Model objects, even then try to avoid it
 It should be considered technical debt if done, but it’s
a relatively harmless area to take on debt
Where should INotifyPropertyChanged and
INotifyCollectionChanged be used?
 Definitely in the View Model
 Occasionally in the View - usually in Custom Controls
and more rarely User Controls
 It’s becoming more accepted to them in the Model
unless added to push updates to a View
 Notifying users from a View Model, i.e. How do I show




a message box?
How do I handle non-command events without code
behind?
Something should or should not be shown based on
state. What goes in the View vs. View Model?
Should I use an additional property or the command
parameter to pass contextual data to a View Model’s
command?
View Models seem to copy all of my Model’s properties
 Message boxes are annoying
 Message boxes are annoying
 Messages to the user are useful
 Use a mediator – Allows you to aggregate messages from
all of your VMs, log them, and display them. Also easy to
test.
 If you only need it in one or two places an
Error/Notification property or, more rarely, event works
well.
 Implement the IDataErrorInfo interface for notifications
related to property validation
 Usually done using an attached behavior, search for
“Attached Command Behavior”
 Can it be handled by binding?
 If absolutely necessary and there’s no logic involved it
can be put into code behind.
http://xkcd.com/292
 Is it a View-only concern? E.g. Master/Detail view
 Bind the detail view to the selected master item
 Is it a View Model concern? E.g. IsEditMode
 Use a DataTemplateSelector if available to switch Views
 Use Triggers, Visual State Manager, or another method
to switch views based on the View Model properties
 Is it a combination? E.g. IsBusy
 Use the Visual State Manager if available
 Would the property be referenced anywhere outside of
the command(s)?
 Does the property make sense in the context of the
View Model’s interface?
 Is the command used in multiple places that would
need to set the property to different objects?
 View Models are not just Façades or Adapters for
Model classes
 View Models are not the code behind for a View
 View Models are an Abstract View or the Model for a
View
 View Models will present multiple Models and
multiple View Models might use the same Model
I love feedback!
Bryan Anderson
bryan.anderson@ilmservice.com
Download