02 xaml data binding basics

27
02 | Basics of View Models Ben Riga http://about.me/ben.riga

Upload: cviga

Post on 29-Nov-2015

41 views

Category:

Documents


1 download

DESCRIPTION

XAML Data Binding Basics

TRANSCRIPT

02 | Basics of View Models

Ben Riga http://about.me/ben.riga

Building Apps for Both Windows 8 and Windows Phone 8 Jump Start

01 | Comparing Windows 8 and Windows Phone 8

02 | Basics of View Models

03 | MVVM ( (Model-View-ViewModel)

04 | Sharing Code

Course Topics

Data binding basics

Data binding: under the hood

Dependency object, dependency property

View Model

INotifyPropertyChanged, INotifyCollectionChanged

Commands

Q&A

Agenda

Data Binding Basics

Writing the code to synchronize a data model with a view can be difficult to maintain and test

Could use a mechanism to help with this task

Data binding lets you synchronize the data displayed in a view with a data source

Data Binding Overview

Each data binding has three parts:

Binding source: an object with data that you want to present (this is the View Model)

Binding target: a DependencyProperty of a FrameworkElement

Binding object: synchronizes data between the source and target, possibly reformatting it with a value converter

Data Binding Overview

Binding engine gets information from the Binding object:

Source and target objects

Direction of the data flow (Binding.Mode property)

Optionally, a value converter (Converter property)

- Instance of a class that implements IValueConverter

Data Binding Architecture

Binding Target (Property)

Binding Source (DependecyProperty /

INotifyPropertyChanged)

Binding

Object

Data Updates

(one-way)

Data Updates

(two-way)

Data Updates

(one-way)

Data Updates

(two-way)

Two ways in XAML to define the source object for a data binding:

DataContext property

- Must bind to a type that implements INotifyPropertyChanged

- Sets the bindings for that element and all child elements

ItemsSource property of a List control

- Must bind to a type that implements INotifyCollectionChanged

• ObservableCollection is a built-in class that implements this - Items contained by the collection must implement INotifyPropertyChanged

Data Binding

Data Binding:

Under the Hood

A DependencyProperty is a special type of property

Can be data bound

Tracked by XAML Binding Engine

For data binding to work, the object with the dependency property must be a subclass of DependencyObject

- FrameworkElement is a subclass of DependencyObject, so all controls can participate in data binding

Dependency Property, Dependency Object

<TextBlock x:Name="DescriptionTextBlock" Margin="12,0,0,0" Text="{Binding Description} " />

Dependency Property Binding Markup Extension Dependency Object

Converters let you bind a target and a source that are different types

For example: suppose you want to show an element only if a bool variable is true

Provide a class that implements IValueConverter

- Implement Convert that converts from the source type to the target type

- Implement ConvertBack that converts from the target type to the source type

- Implement these methods to create any mapping between two types.

Converters

<TextBlock x:Name="MyTextBlock" Visibility="{Binding IsVisibleBool, Converter={StaticResource

BoolToVisibilityConverter}}" />

Binding Mode

One-time: view is populated with data from the model only once, on page load

One-way: view is changed to match the data from the model

Two-way: data in the view and the model is synchronized so changes in one change the other

Binding Modes

<Image Source="{Binding VisualElement.BackgroundImage, Mode=OneTime}" Width="150"

Stretch="UniformToFill" Grid.RowSpan="2" />

More advanced property paths

Instead of just setting the source to a property of the data context object, you can chain together properties to dig into the object:

Use the StringFormat property to format text in data bindings

The property being bound should implement the IFormattable interface (DateTime in this example)

Other Binding Options

<Image Source="{Binding VisualElement.BackgroundImage, Mode=OneTime}" Width="150"

Stretch="UniformToFill" Grid.RowSpan="2" />

<TextBlock Text="{Binding Coupon.ExpirationDate, StringFormat=Expiration Date: \{0:d\}}"

Style="{StaticResource PhoneTextSmallStyle}" FontWeight="Bold" Foreground="{StaticResource

CustomGroupTitleBrush}" Grid.Row="2" HorizontalAlignment="Center"

VerticalAlignment="Stretch"/>

Demo 1: Data Binding

A class that acts as a binding source is considered a View Model

Loosely coupled to a View

- Avoid direct references to individual XAML elements

Exposes properties for binding

Implements INotifyPropertyChanged and raises the PropertyChanged event whenever a property is set

Include business logic to respond to user actions in the view

Makes sure that changes to data are persisted

- Tells a data service to save changes

View Model

View Model Example public class ItemView Model : INotifyPropertyChanged

{ private string _name;

public string Name

{

get { return _name; }

set {

if (value != _name)

{

_name = value;

NotifyPropertyChanged("Name");

}

}

}

public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged(String propertyName)

{

PropertyChangedEventHandler handler = PropertyChanged;

if (null != handler)

{

handler(this, new PropertyChangedEventArgs(propertyName));

}

}

}

Binding source objects (View Models) that are part of a OneWay or TwoWay binding must implement the INotifyPropertyChanged interface

Fire the PropertyChanged event whenever the value of a public property changes

The runtime framework subscribes to this event and uses it to update bound UI elements

One time binding does not require this

INotifyPropertyChanged

Can also bind to lists

Two ways to bind collections of data:

Extend ObservableCollection<T>

Implement IList and INotifyCollectionChanged

Items in the collection must implement INotifyPropertyChanged

In the ItemsPanel of the XAML list element, you are bound to the individual item of the collection

Data Binding with Lists

Let you expose a method like a property

Can attach commands to buttons (of any type) and menu items

Automatically executed by the system

Lets the view notify the code that some action has occurred

For example, when the user clicks a button, the app could clear a canvas or refresh data from a server

Implement the ICommand interface

Execute: code that runs when the command is invoked

CanExecute: called to check if the command is enabled

CanExecuteChanged: raise this event when a command is enabled/disabled

Commands

Commands Example <Button Content="Say Hello" Command="{Binding HelloWorldCommand}"></Button>

class HelloWorldCommand : ICommand

{

public event EventHandler CanExecuteChanged;

public bool CanExecute(object parameter)

{

return true;

}

public void Execute(object parameter)

{

MessageBox.Show("Hello world!");

}

}

class MyView Model

{

private HelloWorldCommand myCommand = new

HelloWorldCommand();

public HelloWorldCommand HelloWorldCommand

{

get

{

return myCommand;

}

}

}

protected override void OnNavigatedTo(NavigationEventArgs e)

{

DataContext = _myView Model;

}

Recap

Binding greatly reduces the amount of code required to synchronize your app data with the data presented in the view

Use a view model to present data to the view and update the model as necessary

The XAML binding engine does most of the work for you

Recap

Use binding markup extensions to link properties of XAML elements to the source

All XAML controls are FrameworkElement , which inherits DependencyObject

Make sure to set the DataContext or the ItemsSource property when data binding

Can do this from code after loading your data

Implement the INotifyPropertyChanged interface in your binding source object

Recap (cont.)

Use converters to bind different source and target types

Properties in the binding property path can be chained together to dig into objects that are containers

Decide which binding Mode (one-time, one-way, two-way) is best for each property

Recap (cont.)

Use commands to run some code when the user interacts with an element, such as clicking a button.

No event handling needed, system automatically invokes the method

Can reuse commands to provide multiple ways to achieve the same thing in the UI

Recap (cont.)

Q&A