Archive for October, 2010

23
Oct
2010

XPF: Data Binding 101 (Part 1) – What, Why, How?

by David Wynne

Data Binding is one of XPF’s features that we’re excited about – bringing data binding to the world of XNA helps to encourage building of loosely coupled applications and helps enable the separation of presentation from implementation logic.  We’ve previously discussed the inner workings of data binding in our insider post but for those whom data binding maybe an abstract concept, this series of posts is designed to introduce you to both the concepts and the implementation.  Let’s walk through what it is, why you should use it and what XPF offers.

What is Data Binding?

Data binding can essentially be thought of as an implementation of the Observer Pattern, where the UI is the observer and the domain model the subject.

“The observer pattern (a subset of the publish/subscribe pattern) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.”
- Wikipedia

In reality XPF turns that concept on its head in that the UI elements maintain the list of subjects and hooks onto them to watch for updates, it also supports two-way conversations between subjects and observers but we’ll come onto that later.

Let’s step back slightly; XPF goes a bit further than the observer pattern so let’s change our language terms to something more fitting.  Instead of “subject” we’ll use source and in-lieu of “observer” let’s say target.  Let’s look at what that means in practical terms:

image

In this example we have a player class that exposes the player’s score via a property.  We also have a user interface which is going to display the player’s score as it updates.  In this example the score property on the player object is the source of our data and the text block in the UI is the target.  In a situation like this we would use data binding to establish a relationship between our player class and our UI once and then never worry about it again, knowing that if we alter the player’s score in our domain model the UI will automatically get updated via data binding.

Why use Data Binding?

Data binding is an enabler of other patterns and practices that ultimately make your life easier and your code easier to manage.

The quest to isolate domain logic from the user interface has spawned dozens of architectural patterns, MVC and MVVM being amongst the most popular at the moment.  Both concentrate on allowing your domain model to be focused on its job whilst being agnostic to any UI that maybe influenced by it.  This has some distinct advantages.

Generally speaking the logic you use to determine whether a player’s score should increase and the logic you use to display that change in score are very different beasts, as such when tackled together they don’t tend to produce particularly focused units of code.

Producing focused, isolated units of code makes your codebase easier to understand and eases unit testing.  If your player class doesn’t care about UI, then it doesn’t need to know anything about any graphics related dependencies, thus a dependency is dropped, unit testing is eased, and your code base is simpler and less brittle as a result.

Data binding encourages this separation by providing a bridge between the two disciplines.

Data Binding in XPF

As mentioned previously, XPF turns the Observer pattern on its head slightly in regards to which side of the equation maintains the list of observers (targets) that should be updated when the subject (source) changes.

In XPF the target maintains the list of sources with which it is bound.  The switch in responsibility here frees up the source (domain model) from being anything much other than a POCO.

The target is a UI element; all elements in XPF inherit from ReactiveObject and expose Reactive Properties which can be bound to.  Together ReactiveObject and ReactiveProperty provide the required mechanisms for data binding to work.

Three modes of binding are supported: one way, one way to source and two way.  The modes describe the direction in which data flows relative to the target.  One way is from the source to the target, one way to source is from the target to the source and two way moves data in both directions.imageWhilst all of the heavy lifting is taken care of by ReactiveObject and ReactiveProperty the source (domain model) side of the equation still has to agree to a couple of rules if it wants to take part.  The source needs to expose a known hook for the binding system to latch onto which it can use as a channel to push data in one or both directions.

In XPF this hook is provided by the new IObservable<T> and IObserver<T> interfaces introduced in .Net 4.0 (and on WP7) which align to the concept of moving data in either direction.  They are the mathematical dual of IEnumerable<T> and IEnumerator<T>, in that they push rather than pull their data.

“The IObserver<T> and IObservable<T> interfaces provide a generalized mechanism for push-based notification, also known as the observer design pattern. The IObservable<T> interface represents the class that sends notifications (the provider); the IObserver<T> interface represents the class that receives them (the observer).”
- MSDN

One way binding expects an IObservable<T> as its source which the binding system subscribes to.  One way to source expects an IObserver<T> to which the binding system can push updates.  Two way expects both.

How to use Data Binding

Continuing on the example application above, the score would be defined in the UI as a TextBlock and we would bind our player class to its text property.

Bindings are always setup against a ReactiveProperty on a ReactiveObject via the Bind() method.  In XPF all controls ultimately inherit from ReactiveObject and most expose a number of ReactiveProperty properties that can be bound to.

Each control exposes the Reactive Properties available for binding as static members, here are some of the Reactive Properties exposed by TextBlock, all of which can be bound to:

TextBlockReactiveProperties

Once we have an instance of a TextBlock we can call its Bind method and specify what property we want to bind to along with the mode and source we want to use.  It’s at this point we decide what binding mode we want to use by providing either an IObservable<T> (one way), IObserver<T> (one way to source) or both (two way):

TextBlockBind

The binding is now set and in the example above any changes to the source provided would update the TextBlock’s text property, meaning we don’t have to worry about updating the UI ourselves.

Don’t worry if all this talk of observables and observers is worrying you, we’ll cover the BindingFactory in a future post that can be used to create bindings around normal typed properties, but it’s good to get an understanding from the ground up.

Next Time…

In the next post in this series we’ll look at a domain object that exposes IObservable<T> and IObserver<T> properties and build a working sample that uses them to create both one way and two way bindings.

18
Oct
2010

XPF Video: Windows Phone 7 User Group Presentation

by David Wynne

At the last Windows Phone User Group, we took to the stage of Imperial College London and gave an introductory presentation on XPF.  For those that weren’t able to make it, we’re pleased to be able to present it to you now in 720p via the magic of IIS Smooth Streaming (we’ll also be making a downloadable version available shortly).

Topics include:

  • Why we need XPF
    • 2D in XNA Today
  • What is XPF
    • Controls
    • Extensibility
  • How to use XPF
    • Live demo: Embedding XPF inside a 3D application on WP7.

We’ve updated the XPF Samples package to include the full source code for the final 3D Basketball Game we built – you can download it here.

Massive thanks go to our good friend Mr Hornsby, the man behind the filming and editing of this presentation and of course Matt Lacey for organising the WPUG.  If you’d like to have a chat about video coverage of your event, drop Steve an email: steve@stephenhornsby.com

12
Oct
2010

XPF Control Tour: ItemsControl

by David Wynne

Updated 2010-10-20: Altered BindingFactory.CreateOneWay<SolidColorBrush> to CreateOneWay<Brush> – co/contravariance isn’t supported on WP7.  ItemTemplate now passes DataContext as an argument of the Func (Build 37+).

As XPF matures the number of controls available increases, but it’s largely down to the early adopter to seek them out and figure out how to use them.  Our thinking here is that most developers will have had some WPF/Silverlight experience so the usage pattern will be easy to work out.  That may have been a little presumptuous on our part, so in a series of short and sharp posts we’ll take a tour through some of the less obvious controls.

First up the ItemsControl, one of my favourites.  In XPF if you want to repeat a block of UI for n number of items, you invariably want an ItemsControl.  Think ListBox, ComboBox or maybe items in a menu.

Let’s look at a complete example and it’s output:

public class MyComponent : DrawableGameComponent
{
    private RootElement rootElement;

    public MyComponent(Game game)
        : base(game)
    {
    }

    public override void Draw(GameTime gameTime)
    {
        this.rootElement.Draw();
        base.Draw(gameTime);
    }

    public override void Update(GameTime gameTime)
    {
        this.rootElement.Update();
        base.Update(gameTime);
    }

    protected override void LoadContent()
    {
        var spriteBatchAdapter = new SpriteBatchAdapter(new SpriteBatch(this.GraphicsDevice));
        var primitivesService = new PrimitivesService(this.GraphicsDevice);
        var renderer = new Renderer(spriteBatchAdapter, primitivesService);

        this.rootElement = new RootElement(this.GraphicsDevice.Viewport.ToRect(), renderer);

        var colors = new List<SolidColorBrush>
            {
                new SolidColorBrush(Colors.Red), 
                new SolidColorBrush(Colors.Blue), 
                new SolidColorBrush(Colors.Yellow)
            };

        var itemsControl = new ItemsControl
            {
                ItemsSource = colors, 
                ItemTemplate = dataContext =>
                    new Border
                        {
                            Width = 50, 
                            Height = 50, 
                            Margin = new Thickness(10), 
                            Background = new SolidColorBrush(Colors.Gray)
                        }
            };

        this.rootElement.Content = itemsControl;
    }
}

image

That’s all standard XPF scaffolding code right up until we define a list of colors and define an ItemsControl.  Things to note:  ItemsSource is set to the list of colors (you can use anything that implements IEnumerable).  The ItemTemplate property is a Func<IElement> (all controls in XPF implement IElement) and is executed for each item specified in ItemsSource, hence we defined 3 colors in our list and we got 3 borders rendered.

The DataContext & Data Binding

At the moment each Border background is gray.  How do we get it to use the colors in our list?  Each item that the ItemsControl generates will have it’s DataContext property set to it’s associated item in the ItemsSource.  Using XFP’s data binding, we can bind to that DataContext property in our ItemTemplate and dynamically assign the background color of each Border:

var itemsControl = new ItemsControl
{
    ItemsSource = colors,
    ItemTemplate = dataContext =>
    {
        var border = new Border
        {
            Width = 50,
            Height = 50,
            Margin = new Thickness(10)
        };

        border.Bind(
            Border.BackgroundProperty,
            BindingFactory.CreateOneWay<Brush>());

        return border;
    }
};

image

Whilst the data context of each item is automatically set by XPF to support various binding scenarios, you’ll also note that the data context is passed as an argument of the ItemTemplate function.  This facilitates run-time decisions about the template that should be returned.

If you’re interested in all the Data Binding options, be sure to check out our Inside XPF: Data Binding post.

ItemsPanel

The way in which the ItemsControl lays out it’s children can be configured via it’s ItemsPanel property.  By default the ItemsControl will use a StackPanel (which itself defaults to an orientation of vertical).  But you can change the ItemsControl to use anything that inherits from Panel, meaning you can apply your own layout logic.  Custom panels is a subject in-upon itself which we’ll cover in a future post, but the process is almost identical to creating a custom panel in WPF/Silverlight, so generally speaking any WPF/Silverlight panel implementation you can find, will work in XPF.

For now, let’s change our ItemsPanel to a horizontal StackPanel:

var itemsControl = new ItemsControl
{
    ItemsPanel = new StackPanel { Orientation = Orientation.Horizontal },
    ItemsSource = colors,
    ItemTemplate = dataContext =>
    {
        var border = new Border
        {
            Width = 50,
            Height = 50,
            Margin = new Thickness(10)
        };

        border.Bind(
            Border.BackgroundProperty,
            BindingFactory.CreateOneWay<Brush>());

        return border;
    }
};

image

 

Observable Collections

In our example so far we’ve been binding our ItemsSource to a List<T> which means after creation our ItemsControl is pretty much not going to change.  If however you set the ItemsSource to a collection that implements INotifyCollectionChanged (such as the commonly used ObservableCollection<T>) the ItemsControl will automatically hook onto CollectionChanged event and dynamically, update it’s children.  All actions are supported meaning you can add, remove, replace or move items in the bound collection and the ItemsControl will automatically update it’s layout to reflect the changes.

Using the ItemsControl with an observable collection and data binding is another great example of XPF helping you separate your presentation and implementation concerns.