02 xaml data binding basics
DESCRIPTION
XAML Data Binding BasicsTRANSCRIPT
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
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
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"/>
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;
}
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.)