MVVM

Seperate KO View formating and ViewModel state

A normal scenario with Knockout is that you want date and number observables to be formatted to the current culture of the client, this is easily implemented in a Knockout extender, something like.

ko.extenders.numeric = function(observable, options) {
    var textValue = null;
    return ko.computed({
        write: function(value) {
            textValue = value;
            var parsed = Number.parseFloat(value);
            if(!isNaN(parsed)) {
                observable(parsed);
            } else {
                observable(null);
            }
        },
        read: function() {
            var value = observable();
            if(value == null) {
                return textValue;
            }

            return value.toLocaleString(); //This  can be replaced with for example the Globalize plugin 
        }
    });
};

Use it like

this.amount = ko.observable().extend({ numeric: true });

The problem with this approach is that the ViewModel will no longer work against numbers it will work against formatted strings, so this.amount() will return a string instead of a number. This is very bad practice in a View/ViewModel seperation stand point. (more…)

Advertisements

Single Page Application with Sub-routing

One of my colleagues is working on a Single Page Application, he asked me for help on a solid design for routing and specifically about sub-routing. Sub-routing in a SPA is complex, as an example when you click a link in a list you want that item to be presented in a modal window. If you close the modal window and press back in the history you want it to show again, and if you press forward you want it to close. I choose to attack this problem with an Event Aggregation approach, where changes to the route resulted in a change event being fired to any listener. (more…)

MVVM with Excel and Caliburn.Micro

One of my colleagues needed to modernize a tool we had for Excel. He asked me for suggestions, since he knew I’m into modern UI development. I know very little about the Excel API but after some googling I found out that you are limited to Winforms. There is however a control in Winforms called ElementHost that let you host WPF elements in Winforms. This coupled with a custom Bootstrapper for CM will enable you to develop sleek MVVM tools in Excel.

The Boostrapper will act as an entry point for our Caliburn enabled app. It needs to inherit from BootstrapperBase rather than the standard generic base class Bootstrapper of TModel.

public class Bootstrapper<TModel> : BootstrapperBase
{
    private readonly StandardKernel kernel;

    public Bootstrapper(ElementHost host)
        : base(false)
    {
        kernel = new StandardKernel();

        Start();

        var model = kernel.Get<TModel>();
        var view = ViewLocator.LocateForModel(model, null, null);
        ViewModelBinder.Bind(model, view, null);

        host.Child = view;
    }

    protected override void Configure()
    {
        kernel.Bind<IWindowManager>().To<WindowManager>().InSingletonScope();
    }

    protected override object GetInstance(Type service, string key)
    {
        return kernel.Get(service);
    }

    protected override IEnumerable<object> GetAllInstances(Type service)
    {
        return kernel.GetAll(service);
    }
}

Its constructor takes the ElementHost as argument and then starts CM using the Start method on the base class. We need to hook up the ViewModel manually and its done like.

var model = kernel.Get<TModel>();
var view = ViewLocator.LocateForModel(model, null, null);
ViewModelBinder.Bind(model, view, null);

First we create the ViewModel using Ninject, this way any dependecies for that model will be injected by Ninject. Then we ask CM to locate the WPF view using its convention based helper class ViewLocator. After we get the view we Bind it to the model using another CM helper class called ViewModelBinder.

Last but not least, we need to hook up the WPF element to the Winforms ElementHost.

host.Child = view;

Embedded resources

Alan Rutter asked me how to load embedded resources like themes etc.
App.xaml wont load in a none WPF project so you need to-do this manually like

var dict = new ResourceDictionary {Source = new Uri("Resources.xaml", UriKind.Relative)};
var app = new System.Windows.Application(); //This will load Application.Current
Application.Current.Resources.MergedDictionaries.Add(dict);

Auto generated CRUD forms with Knockout

For the last two years I’ve been working for the asset management at a major Swedish bank. At such a institution CRUD is inevitable and we all know that most devs prefer working with rich domain systems over CRUD. CRUD also generate a lot of similar or duplicated code. In my latest project I wanted to do something about this and decided to create a convention based API to auto generate these forms.

(more…)

Convention based MVVM with Knockout

One of my most popular Open source projects, FreePIE, is a WPF application and it utilizes a library called Caliburn.Micro. The main idea for that library is to minimize the use of explicit declared bindings and use conventions to implicit bind to the ViewModel under the hood. As an example, if you have a button called Save and a method called Save on your VM, Caliburn.Micro will make sure these are bound.
This is a welcomed tool since XAML bindings are, to say the least, verbose.

Bindings get even more verbose in the Knockout world because of the fact that you can write inline JavaScript in the bindings, fact is the entire data-bind attribute is inline JavaScript that is executed by Knockout. I’ve seen that bindings like these and worse are common out there.

<button data-bind="enable: errors().length === 0">Save</button>

I started to write a Convention based library called Knockout.BindingConventions a year ago and I added support for Knockout 3.0 a while back. Even though the library isn’t new I thought I could write about it, it’s a good way to get to know the inner working of Knockout and also convention over configuration. (more…)