Posts Tagged ‘data binding’

8
Feb
2013

Working with data and SVG graphics

by Stephen Fulljames

photo

On a recent project we had a requirement to provide a number of game-like interactions which didn’t really fit, design-wise, into the rather boxy constraints of HTML elements. Probably as recently as a couple of years ago you would have automatically turned to Flash to create these interfaces, but with a need to make the games work on mobile and other devices where Flash support is either absent or a battery drain we looked around for alternatives.

In the post-Flash rich-UI space there are currently two main options – Scalable Vector Graphics (SVG) and Canvas. SVG has actually been around a fairly long time, but adoption on the web has been held back until recently by browser support. It’s the definition of vector (line-based) graphics in an XML document which are drawn to the screen, with the benefit that the drawing can be manipulated by altering the properties of each vector. Canvas, on the other hand, is a relative newcomer and thought of as part of the “HTML5″ family of technologies. It’s a bitmap (pixel-based) format so each update to a canvas object involves over-writing the pixels that were there before.

Both have their uses, and in fact we ultimately used both in the overall project in the places that suited their strengths. But for this particular one, a multiple choice quiz based on the relationships between people and objects, SVG seemed like a natural fit.

Using Raphäel

Based on past experience with it, I chose Raphäel as the SVG library to base the work on. While this was a great head start – Raphäel provides a nice API to work with the SVG DOM and appropriate fallbacks for older browsers – in previous uses I hadn’t done much in the way of interactivity and this is where things started to get complicated.

Binding Javascript event handlers to SVG elements works comparably to HTML, and this is fine when a click or touch on an element affects only itself. In the context of a game where multiple elements need to be changed, it becomes a headache to keep track of state and what everything is supposed to be doing.

In HTML this problem has been largely solved with the rise of Javascript MVC libraries, where the state of a page or application is held as a model in Javascript and bindings to the DOM are used to update the UI based on changing data or user input. This was exactly what we needed for our game, but on initial investigation it looked like there wasn’t really anything directly comparable for SVG.

At first the whole game area was created in SVG, but given this event/state issue and that there isn’t much sophistication in the SVG 1.0 spec for text handling – especially wrapping of strings in a container element – we switched to rendering the multiple choice selections with HTML. This is the only part the user directly interacts with, and as HTML it could be bound directly to the Knockout viewmodel we stored the game state in. Changes in the model could then fire the appropriate functions to update the state of the SVG object and sanity could be preserved.

This reduced a lot of complexity and made the UI easier to manage but it still feels like a compromise solution as the smoother styling and scaling effects available in SVG couldn’t be applied to the HTML parts of the game.

What else is out there

However Raphäel isn’t the only SVG library out there, and other options might get closer to what we really needed. Pablo is described as being a combination of Raphäel, jQuery and Underscore for SVG, and an initial look shows a nice API with some useful stuff like duplication, templating and DOM traversal. As is often the way of these things, Pablo popped on to our radar just as the project was finishing.

D3.js is a popular charting and data visualation library which is able to transform documents based on changing data. However there’s a higher level of complexity here and so in the constraints of the project there wasn’t time to investigate it fully.

Another really interesting looking SVG library is Bonsai which is used as the basis of a Flash to HTML5 conversion service. And on the other side of the modern-rich-UI party, Canvas Query is a new tool positioned as a jQuery-style wrapper for the Canvas element.

What else is needed

While there are plenty of sophisticated options for pure charting in SVG, which can also handle data entering and leaving the object, it feels to me as if there is a missing link in a nice handler for interactivity and application state.

Or perhaps the solution is in one of the tools listed above and I haven’t looked hard enough yet.

Either way, I’m going to look into this in more detail. Something that can act as a bridge between popular Javascript MVC libraries – the likes of Knockout, Backbone and Angular – and SVG rendering would be a useful tool, and if it doesn’t already exist it would be worth creating.

2
Jan
2012

HTML5 prototyping with Node and Knockout

by Stephen Fulljames

Over the past couple of months, a small team at Red Badger has been working on a number of HTML5 prototypes for an interesting client. Speed of development and easy iteration have been essential so we’ve taken the opportunity to try out a new technology stack which has given what we were looking for and is exciting the whole business.

Maybe a demanding prototype schedule isn’t the ideal place to chuck away everything you’re used to and start afresh, but actually a lot of the front-end development has built on tools and themes we’ve worked with throughout 2011 and we’ve found that the speed and ease of using Node has more than compensated for the learning curve. So, what have we been using?

Server

Node – Underpinning everything we’ve been doing in our prototyping project; Node is fast, event-driven and built on Javascript. Its been fascinating for myself, as a primarily front end developer, and Stuart with an ASP.net background to see how our respective specialisms are converging on a single set of tooling. The module loading system, NPM, which is similar to Ruby’s Gem ecosystem, also makes it incredibly easy to pick up and play with the many extensions that are out there – and to create your own too.

Express – A development framework for Node, giving RESTful routing and content negotiation. After working with Open Rasta in .net MVC on a previous project, the ease of setting up applications using Express has been a delight.

Jade – With Express providing the application routing and view rendering, we next add Jade for templating. A HAML-style syntax, offering us simplicity and brevity but compiling to really well-formed HTML and easy to use with HTML5 data-* attributes for Knockout (which we’ll come to later). In fact having used Jade for a while now I’m not sure I want to go back to writing “proper” HTML.

Step / Async – Node’s asychronicity takes some getting used to after having worked with linear control flows for such a long time. Imagine AJAX callbacks as the fundamental way a language works – you can’t rely on other parts of your application providing data at the moment you need them, so you need to be able to create queues for parallel and serial execution. Step and Async are two modules we’ve tried out for this, both have their benefits but Async seems to be slightly in the lead for what we’re doing.

Now – The other great benefit of Node is its ability to serve real-time applications, and the Now module takes this to almost magical levels. Existing as a namespace on both the client and server simultaneously, you can call client methods from the server (and vice-versa) to push data instantly as a general or targetted broadcast. Seeing this in action has really convinced us that Node is something to get excited about, and has wowed the client too!

Client

Knockout – We used Knockout on other projects throughout 2011, but with Node’s inherent ability to supply real-time data its really coming to its own. It’s a Javascript library implementing the MVVM (Model-View-View Model) pattern, which should be familiar to Silverlight developers, and makes rich UIs a breeze to update. The new 2.0 version, released during the Christmas break, removes the reliance on jQuery for its default templating which really opens up its flexibility.

Underscore – Described a ‘utility-belt library’ for Javascript, Underscore is another tool that is compimentary to the likes of jQuery and adds a whole raft of functional programming methods to objects and arrays (among other things). It also runs as a Node module so we can make use of it on both client and server, great for code consistency.

Ender – In fact with Knockout and Underscore at work, it was beginning to feel like jQuery had been relegated to just a “ready” utility, DOM selection and effects. That’s a lot of weight for something we weren’t using very much so as an alternative we’re trying out Ender, which allows you to compile your own library from smaller modules – such as the lightweight DOM selector Qwery. And it all installs and builds in a similar approach to NPM.

LESS – A CSS pre-compiler, and another tool we used during 2011, but as a native Node module its integration is now much easier. If you’re developing in a Node environment you can use it to watch for LESS file changes and compile locally (we also use LESS.app on OS X), and then deploy the LESS and have the server startup create a complled and minifed version in production. Alongside Jade and Coffeescript its beginning to feel like compilation from more efficient syntaxes down to browser-readable files is becoming a key element to web development.

The whole picture

As well as this Javascript-oriented development we’ve also been trying out MongoDB and Redis for data storage as part of the stack, with equally encouraging results. And to make project compatibilty and pair programming between our Windows, Mac and Ubuntu users easier we’ve given JetBrains’ Webstorm (and PHPStorm) IDE a thorough test drive – given it has all that familiar Reshaper goodness from their Visual Studio tools its looking like a great combination so far.

It might seem that, with all these Javascript-heavy technologies in HTML5 documents, older browers won’t get a look in. As we’re prototyping on this project perhaps its not important, but actually support is pretty good. Every view Node creates is sent as rendered HTML, just like any other web server, and in fact due to its speed we’re finding that we can make sites less “AJAX-y” than we might otherwise – which of course is better overall for accessibility and discoverabilty. On the client side, Knockout is compatible back down to IE6 and even the ‘magic’ of Now is mobile compatible, with beta support for older IE versions. Of course we want to move away from those legacy browsers as much as any other developer, but if it’s a client requirement this stack can still provide it.

So as a result of these experiences we’re investigating using Node and its related technologies more widely at Red Badger during 2012, its already looking like its going to be an exciting year!

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.

13
Sep
2010

Inside XPF: Data Binding

by Stuart Harris

Updated 2010-09-20: Reflects the removal of the generic type parameter TOwner from ReactiveProperty (starting Build 20).

Neuroanatomical Connectivity Macaque by Arenamontanus In the previous post in this series, we discussed XPF’s Reactive Properties – the counterpart to Silverlight’s Dependency Properties.  Reactive Properties allow you to data bind to any source that implements the new .Net 4.0 IObservable<T> (for one-way binding) and/or any source that implements IObserver<T> (for one-way-to-source binding).  Two-way binding is simply a combination of the two.

The Reactive Object

In Silverlight, all UI Elements are derived from DependencyObject which the MSDN documentation says “Represents an object that participates in the dependency property system”.  In XPF all UI Elements are derived from ReactiveObject which represents an object that participates in the reactive property system.  ReactiveObject not only stores the current values of all the element’s reactive properties, but also allows you to bind to them in either (or both) directions.

The Bind method has overloads that allow you to bind a ReactiveProperty one-way to an IObservable, one-way-to-source to an IObserver or two-way to both.

The Binding Factory

So what do you do if the object you want to bind to doesn’t expose an IObservable/IObserver?  This is where the BindingFactory comes in.  The BindingFactory will create IObservables and IObservers around properties on either the data context or a specified source.

Binding to reactive properties, or properties on POCOs and objects that implement INotifyPropertyChanged is fully supported.  This enables element-to-element binding in addition to the use of familiar binding patterns often used in WPF/Silverlight such as Model View ViewModel (MVVM).

The observable/observer that the BindingFactory creates for you is internally wrapped in a Binding object which allows for either immediate or deferred resolution of the binding.  Immediate resolution is used when a reference to the source is provided, but if you are binding to an element’s data context then the binding resolution is deferred until the start of the Measure layout phase.  Deferred bindings are great because they allow the data context to be set or changed after the element binding has been declared.  This is essential for controls that use templates such as the ItemsControl.  The Binding’s resolution is handled seamlessly.

All data binding scenarios are supported.  The following table shows the various combinations of source objects/properties in each mode.  Note that binding to POCO properties works in both directions, but without INotifyPropertyChanged (INPC), one-way binding effectively becomes “one-time”.

Data Context
/Source Object
Reactive
Property
INPC
Property
CLR
Property
One-way Supported Supported Supported Supported
(one-time)
One-way-to-source Not applicable Supported Supported Supported
Two-way Not applicable Supported Supported Supported
(one-time and one-way-to-source)

Show me some code

Here are the overloads to ReactiveObject’s Bind method:

Bind

You’ll notice that because it’s a generic method, the parameters are strongly typed to match the target ReactiveProperty specified.  The scenario in the screenshot above shows binding to a source reactive property on the element’s data context.  The specification for this scenario looks like this:

[Subject(typeof(ReactiveObject), "One Way")]
public class when_there_is_a_one_way_binding_to_a_property_on_the_data_context
{
    private const double ExpectedWidth = 10d;

    private static SourceObject source;

    private static ContentControl target;

    private Establish context = () =>
        {
            target = new ContentControl();

            IObservable<double> fromSource =
                BindingFactory.CreateOneWay<SourceObject, double>(SourceObject.WidthProperty);
            target.Bind(UIElement.WidthProperty, fromSource);

            source = new SourceObject();
            target.DataContext = source;
            target.Measure(Size.Empty);
        };

    private Because of = () => source.Width = ExpectedWidth;

    private It should_update_the_target = () => target.Width.ShouldEqual(ExpectedWidth);
}

Because we’re binding to the control’s data context the binding resolution is deferred until the target is measured.

Using the Binding Factory

Here are some examples of how to create Bindings using the Binding Factory.  Those that involve the data context are all deferred and those where the source is specified are all immediate.  An IDualChannel simply encapsulates both an IObservable and an IObserver so that data can flow in both directions (to and from the source).

Notice that you only need to specify type parameters when there is not enough information in the method’s parameters for the compiler to infer the types involved:

To the Data Context

IObservable<double> fromSource =
    BindingFactory.CreateOneWay<double>();

IObserver<double> toSource =
    BindingFactory.CreateOneWayToSource<double>();

To a Reactive Property on the Data Context

IObservable<double> fromSource =
    BindingFactory.CreateOneWay<SourceObject, double>(SourceObject.WidthProperty);

IObserver<double> toSource =
    BindingFactory.CreateOneWayToSource<SourceObject, double>(SourceObject.WidthProperty);

IDualChannel<double> fromAndToSource =
    BindingFactory.CreateTwoWay<SourceObject, double>(SourceObject.WidthProperty);

To a Reactive Property on a specified Source

IObservable<double> fromSource =
    BindingFactory.CreateOneWay(source, SourceObject.WidthProperty);

IObserver<double> toSource =
    BindingFactory.CreateOneWayToSource(source, SourceObject.WidthProperty);

IDualChannel<double> fromAndToSource =
    BindingFactory.CreateTwoWay(source, SourceObject.WidthProperty);

To an INotifyPropertyChanged or CLR Property on the Data Context

IObservable<double> fromSource =
    BindingFactory.CreateOneWay<SourceObject, double>(o => o.Width);

IObserver<double> toSource =
    BindingFactory.CreateOneWayToSource<SourceObject, double>(o => o.Width);

IDualChannel<double> fromAndToSource =
    BindingFactory.CreateTwoWay<SourceObject, double>(o => o.Width);

To an INotifyPropertyChanged or CLR Property on a specified Source

IObservable<double> fromSource =
    BindingFactory.CreateOneWay(source, o => o.Width);

IObserver<double> toSource =
    BindingFactory.CreateOneWayToSource(source, o => o.Width);

IDualChannel<double> fromAndToSource =
    BindingFactory.CreateTwoWay(source, o => o.Width);

Clearing a Binding

To clear a binding simply call the ClearBinding() method on the relevant control, specifying the reactive property whose binding you want to clear:

element.ClearBinding(Border.BorderBrushProperty);

Because an instance of ReactiveObject can only have one binding per property, calling the Bind() method replaces any existing binding.  Internally it calls ClearBinding() before attaching the new binding.

When a binding is cleared, its subscription to the source is automatically disposed.  This releases any attached event handlers (created automatically in order to listen to PropertyChanged events) which helps prevent memory leaks.  This is a great feature of Microsoft’s Reactive Extensions (Rx) that frees the developer from worrying about having to un-hook event handlers when an observer is no longer interested in the event.

Even though there can only be one binding at a time to an element’s property, you can still merge multiple observables together using any of the Rx combinators (Merge, Zip, CombineLatest etc) if you want your reactive property to listen to more than one source.

Summary

We hope that the binding system in XPF is simple to understand and easy to use.  Whilst the underlying property system in XPF is push based (rather than pull), we’ve strived to keep the development experience familiar to Silverlight and WPF developers.

The tight integration with Reactive Extensions makes it extremely flexible and powerful.  The statically typed nature of the binding and property system makes it intuitive, discoverable and refactoring friendly.  The absence of any magic strings means that there should be no run-time binding exceptions when a deferred binding cannot be resolved.  Binding to nested properties is currently not supported, but we plan to introduce this using the same strongly typed lambda expression syntax shown above.

Please download the latest build, play about with it and feedback to us!

Inside XPF Series: