WinRt

WinRT : StyleMVVM Demo 1 of 2

As I promised I have now started to write up an article or 2 on using the truly awesome WinRT MVVM framework StyleMVVM.

The 1st part of this series (my gut feeling is there will only be 2 parts), is available right now here :

http://www.codeproject.com/Articles/676432/WinRT-StyleMVVM-Demo-1-of-2

In this article I discuss what StyleMVVM gives the average developer that might choose to use it. The article is definately written from an ed user point of view. I think once you have read the article you will see that StyleMVVM is indeed very useful.

Anyway I guess I better start on part 2 now huh.

 

 

Advertisements
WinRt

WinRT : StyleMVVM Best Of Breed MVVM Framework (IMHO)

About a year ago I contacted by this uber sharp american guy called Ian Johnson, who asked me if I would be so kind as to review his upcoming Windows 8 MVVM library. I stated that I was currently on holiday, but when I got back I would be glad to. Now I have been in pretty much constant contact with Ian over the past year and have been fielding his questions, and we have even written a joint article (Expression API Cookbook) . What immediately struck me about Ians framework (here after known as StyleMVVM) was how feature rich it was, and how well thought out it all was. Remember I have taken time to look at his code base.

At the time I was lucky enough to be asked to be an advisory member for the new PRISM offering for Windows 8 code name “Kona”. I didn’t really have enough time to do much on this but it was still an honor.  Though I have since spent quite a bit of time getting to known “Kona” now known as “PRISM for Windows Runtime“.

Now I love PRISM and have nothing but respect for that team, and previous team members, but I have to also say at the moment, I prefer the StyleMVVM offering, as I think it is just more feature rich, and some of the code seems to be better to use than PRISM for Windows Runtime.

One thing I really liked in StyleMVVM  was the fact that Ian had written a Expression Tree (fast as hell) IOC container from scratch. He has bench marked this and it is rihgt up there, with speeds far exceeding Castle / Unity and AutoFac. It is based around the MEF style attribute model, but fluent registration is also happening any second now (I know I have seen the beta versions of it, and it looks very cool). Ian is very proud of this piece of StyleMVVM , and rightly so, its awesome.

Now that is no small thing, for a single individual to come up with a framework as feature rich as one of the big boys in the MVVM arena, kudos to Ian.

I believed in Ians work so much I have been working on a demo app using it in my spare time. This demo app will be the source for a series of articles on how to use StyleMVVM which I hope to have out there in the wild very soon. You will hear about it here. In the mean time I just want to list some of the features of StyleMVVM, which I have shamelessly stolen from the StyleMVVM codeplex site.

Some of the core features are:

  • StyleMVVM is the only MVVM toolkit for Window Store App that supports all three development languages C#, C++/CX and HTML/JS. Allowing you to export components written in C++/CX and import them into a C# applications.
  • Built in validation engine that supports ValidationAttributes, Fluent validation and Method validation depending on your needs. You can validate ViewModels as well as DataModels.
  • Conventions module to allow for easier development, as well as templates to setup your project to use conventions.
  • Event Handlers can be easily hooked up to your view model using the simple syntax View:EventHandler.Attach=”EventName => ViewModelMethod($sender,$eventArgs); etc…”
  • Supports Regions similarly to Prism with region registration happening in XAML and navigation being driven from the ViewModel
  • Attribute Based IoC container (Export, Import), container is also environment aware and sorts exports accordingly returning the best match at Locate time (RunTime, DesignTime, UnitTest).
  • Fluent interfaces for configuring IoC Container programatically (required for C++/CX and Windows Runtime Components)
  • Design time ViewModel support. ViewModels are located at design time using IOC so you can use your real ViewModel and replace your IDataService with a Faux version for Design and UnitTest.
  • Auto Registration of Views & WCF Clients (i.e. all classes inheriting from ClientBase<T> & Page)
  • Implementations for ICommand and Attached Event Commands.
  • Messenger service that is Dispatcher Aware (i.e. handlers are called back on the proper dispatcher)
  • NavigationViewModel that is tied into the Metro Page Navigation system (Supporting Navigate method & Navigation Events)
  • Extensible logging solution
  • Configuration service that is expandable by Exporting the IConfigurationStorageProvider interface
  • Improved Suspension Manager (auto adds DataContract classes to KnownTypes)
  • IMessageBoxService & IFilePickerService wrappers that allow you to mock out your dialogs for Design and Unit Testing purposes
  • ICharmService make creating flyout easy by automatically registering charm controls with the SettingPane.
  • ITileService, IBadgeService, & IToastService allow for easy updates of tiles and toasts.
  • IActivationService that can create or clone any Object (satisfying Imports and message registration)
  • ITransformService can transform data objects from one type to another using reflection and Linq Expressions, you can use the Transform attribute to give the service hints on how to transform the property.
  • Visual Studio Template for Projects and Items

So you can expect to see some more material on how to use StyleMVVM very soon. If you just can’t wait, grab the code and have a look at the demo, which is very good and showcases most of the features very nicely.

Uncategorized

Node.Js : As A WebSocket Relay And Possible Filter

I was At work the other day and my boss was pushing (nicely) my team lead and I to create a XMAS present for him. What we basically wanted was to capture certain information about certain event that were occurring in the system in real time and have them sent to a web site. I have done something like this in the past using Duplex WCF and MSMQ and SignalR.

This time I thought I just can’t be bother to write all that plumbing and thought about it, and I decided we could go with a simple node.js server, that would serve up a static html page. The static html page would use the node.js and one of the awesome node.js packages namely socket.io. I am fully aware of the awesome Fleck WebSocket library, that does indeed allow you to send data from a .NET client directly to a static HTML page using the Fleck WebSocket API.

Thing is we wanted to filter out certain things, which was not really achievable using Fleck, and it is something that socket.io does very well, so we went with socket.io. I am now going to show you the code, it should however be noted that the code below doesn’t include any filtering, but that is possible using socket.io, where you can broadcast, only send to certain client, send a private message and so on, it really is very good.

So what does the code do again, well it allows a .NET Client to send data via a WebSocket to a node.js server, where it is read and pumped out to a static HTML page using  socket.io. Here is the entire code for the .NET client

public class DemoMessage
{
    public int Type { get; set; }
    public string Description { get; set; }

    public DemoMessage(int type, string description)
    {
        this.Type = type;
        this.Description = description;
    }

    public DemoMessage()
    {

    }
}

class Program
{
    internal static DataContractJsonSerializer jss;

    public async void Run()
    {
        int messageId = 1;
        bool shouldRun = true;
        string exitCode = "Q";

        try
        {
            while (shouldRun)
            {
                Console.WriteLine("Enter you new message value");
                string dataEntered = Console.ReadLine();

                if (dataEntered.Equals(exitCode, StringComparison.CurrentCultureIgnoreCase))
                {
                    shouldRun = false;
                }
                else
                {
                    WebClient client = new WebClient();
                    NameValueCollection values = new NameValueCollection();
                    DemoMessage mess = new DemoMessage(messageId++, dataEntered);
                    AddValue(values, "DemoMessage", mess);
                    Console.WriteLine("Uploading values");
                    client.UploadValuesAsync(new Uri("http://localhost:3000/MessageReceive"), values);
                }
            }

        }
        catch (Exception ex)
        {
        }
    }

    static void Main(string[] args)
    {
        new Program().Run();
    }

    internal static T GetValue(Byte[] results) where T : class
    {
        using (MemoryStream ms = new MemoryStream(results))
        {
            jss = new DataContractJsonSerializer(typeof(T));
            return (T)jss.ReadObject(ms);
        }
    }

    internal static void AddValue(NameValueCollection values, string key, object value)
    {
        jss = new DataContractJsonSerializer(value.GetType());
        using (MemoryStream ms = new MemoryStream())
        {
            jss.WriteObject(ms, value);
            string json = Encoding.UTF8.GetString(ms.ToArray());
            values.Add(key, json);
        }
    }
}

And now onto the node setup. I am using node with Express, and full instructions can be found in the node codes README.txt (though if you download attached code you won’t need to do anything other than install node.js) The node.js application

var express = require('express');
var mess = require('./routes/messageReceive');

var http = require('http');
var path = require('path');
var app = express();

// all environments
app.set('port', process.env.PORT || 3000);
//app.set('views', __dirname + '/views');
//app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));

// development only
if ('development' == app.get('env')) {
  app.use(express.errorHandler());
}

var server = http.createServer(app);
var io = require('socket.io').listen(server);

app.post('/MessageReceive', function (req, res) {
	mess.ReceivePost(req, res, io);
});

server.listen(app.get('port'), function(){
    console.log("Express server listening on port " + app.get('port'));
});

It can be seen from this that there the "Static" content csn be served from the "public folder", and there is a single route which accepts the POST data, called "MessageReceive"

exports.ReceivePost = function (req, res, io) {

    console.log('RAW body' + req.body);

     var requestJsonString = JSON.stringify(req.body);
     console.log('STRINGIFIED body' + requestJsonString);

     var requestJson = JSON.parse(requestJsonString);
     console.log('requestJson :' + requestJson);

     var messageJson = JSON.parse(requestJson['DemoMessage']);
     console.log('messageJson " ' + messageJson);

	 console.log('Message Seen');
	 console.log('Type was :' + messageJson.Type);
	 console.log('Description was :' + messageJson.Description);

     io.sockets.emit('newMessage',
         {
             type: messageJson.Type,
             description: messageJson.Description
         });
     res.write('ok');
};

So this code takes the request (from .NET code) and sends it out on the WebSocket. The last peice of the puzzle is the static HTML page that will be the client end of the WebSocket. Lets look at that next. Which is shown below

$(document).ready(function () {

	var socket = io.connect('http://localhost');
	socket.on('newMessage', onNewMessage);
	alert('In the Demo page');
});

function onNewMessage(data) {
    console.log('onNewMessage');
    console.log(data);
	alert('message description ' + data.description + ' message type ' + data.type);
}

All you need to do it run the node command line, change to the directory where you have the node code, type "code app.js" and then launch a browser and point it to http://localhost:3000/demopage.html and then run the .NET code, and send some messages, you should see the static HTML alert your typed .NET messages. Enjoy As usual here is a small demo app : NodeRelay.zip

WinRt

WinRT : My First Impressions

So I have just finished doing my 1st WinRT demo article (and yes it is for an article for codeproject), which I will have up soon. Coming from a place where I was working a lot with WPF I thought it might be a good idea to capture some of my thoughts/current gripes when working with Win8/WinRT.

I have tried to be as pragmatic as possible, and view WinRT as a v1 thing, which will (hopefully) get better in time. That said there were certain things I just missed a lot. I think what I will do is just list some of the things I found lacking when I was doing my little demo app, and then I will talk about how I found the whole Win8/WinRT ecco system.

Some Of The Issues That Bugged Me

So here is a list of things that I found a bit odd/off, now that is not to say that these will not get fixed, but they still bugged me all the same

XAML Issues

  •  DependencyProperty system, looked far less able when compared to WPF
  • On more than 1 occassion I found that my ComboBox ItemSource Binding must appear before SelectedItem Binding in XAML if you want SelectedItem to populate correctly from the ViewModel (this seemed to be a problem in 8.0 at least), also I believe I have seen this bug before in days of old in both WPF and SL
  •  No binding in setters within Styles (even SL has this now in  SL5). This one needs fixing like NOW. Its plain wrong, and the work around sucks
  •  RelativeSource binding is far less able when compared to WPF
  •  Visibility is lacking “Hidden”, which is actually useful
  •  No DependencyPropertyDescriptor
  •  Can’t do BasedOn style that allows you to BasedOn default style  (or maybe I just didn’t know how to do it)
  •  No x:Static markup extension. This is extremely useful for binding to singleton instance (which I use for all my ValueConverters)
  •  No x:Type markup extension
  •  No custom markup extension
  •  No DynamicResource markup extension
  •  No VisualStateManager.GoToElementState(..)
  •  I may be wrong on this, but didn’t seem to be able to have nested VisualStates one for top level control, and then some for some inner control.
  • WebView is still 2nd class citizen, in certain scenarios its still ALWAYS on top.
  • ListBox backgroundColor / BorderBrush do not work that well with Focus, you have to restyle either whole control or ListBoxItem (container) taking into account Focus VisualState (I think this is a pain others probably disagree)

Decision Issues

  • No DatePicker control (ok its coming in 8.1, but please what the heck, do people not need to amend/pick dates in Windows 8. This is plain lazy)
  •  No Triggers in Styles/DataTemplates. Follows the SL model of VisualState(s). In my opinion (and I am not alone here) Triggers are and ALWAYS will be more powerful than visual states. At least give us both and let us use which model we prefer
  • No Blend interactivity interactions. My god so we are now back in WPF v1 land where we have to right our own attached behaviors for everything. Practically any XAML developer will have become accustomed to using the standard Blend interactions / behaviours. We want these back.

Plain Weird Issues

  • Enumerable.Range(2013,2023) plain doesn’t work. Try that and see what you get. It is very odd
  •  DateTime object is very limited compared to .NET version

What Was The Win8 Ecco System Like To Use

WinJS or C#

Now as I have stated I am predominately involved with WPF, I do however also do a fair amount of ASP .NET MVC /  and MVC/MVVM client side Javascript development (Knockout.js / Angular.js / BackBone.js). So what language did I pick when doing my Win8 article. For me that was a no brainer, C#. Too be honest I find the whole idea of a bastardized version of Javascript that will only run on Windows8.* completely alien. If you believe the press, its plain JavaScript. Sure it is.

The other thing I just don’t see it as a very transferrable skill (oddly XAML is, its in WPF / SL and now WinRT). For example if I used just WinJS every day, do you think that would be a transferrable skill, cos I sure don’t. Lets say I was doing TypeScript or native JavaScript would they be transferrable skills, well yes they would. C# on the other hand, still very much in vogue if you ask me. So that 1st language choice hurdle was an easy one for me to make.

Others may strongly disagree, but that was just my take on it.

App Structure

I have to say I am not mad keen on the overall application structure. I mean have you seen how much boiler plate code you get in App.xaml.cs, here it is for a new project. Thats nasty if you ask me:

///
/// Provides application-specific behavior to supplement the default Application class.
///
sealed partial class App : Application
{
    ///
/// Initializes the singleton Application object.  This is the first line of authored code
    /// executed, and as such is the logical equivalent of main() or WinMain().
    ///
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

    ///
/// Invoked when the application is launched normally by the end user.  Other entry points
    /// will be used when the application is launched to open a specific file, to display
    /// search results, and so forth.
    ///
    ///Details about the launch request and process.
    protected override async void OnLaunched(LaunchActivatedEventArgs args)
    {
        Frame rootFrame = Window.Current.Content as Frame;

        // Do not repeat app initialization when the Window already has content,
        // just ensure that the window is active

        if (rootFrame == null)
        {
            // Create a Frame to act as the navigation context and navigate to the first page
            rootFrame = new Frame();
            //Associate the frame with a SuspensionManager key
            SuspensionManager.RegisterFrame(rootFrame, "AppFrame");

            if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
            {
                // Restore the saved session state only when appropriate
                try
                {
                    await SuspensionManager.RestoreAsync();
                }
                catch (SuspensionManagerException)
                {
                    //Something went wrong restoring state.
                    //Assume there is no state and continue
                }
            }

            // Place the frame in the current Window
            Window.Current.Content = rootFrame;
        }
        if (rootFrame.Content == null)
        {
            // When the navigation stack isn't restored navigate to the first page,
            // configuring the new page by passing required information as a navigation
            // parameter
            if (!rootFrame.Navigate(typeof(GroupedItemsPage), "AllGroups"))
            {
                throw new Exception("Failed to create initial page");
            }
        }
        // Ensure the current window is active
        Window.Current.Activate();
    }

    ///
/// Invoked when application execution is being suspended.  Application state is saved
    /// without knowing whether the application will be terminated or resumed with the contents
    /// of memory still intact.
    ///
    ///The source of the suspend request.
    ///Details about the suspend request.
    private async void OnSuspending(object sender, SuspendingEventArgs e)
    {
        var deferral = e.SuspendingOperation.GetDeferral();
        await SuspensionManager.SaveAsync();
        deferral.Complete();
    }
}

Coming from other stuff like there is a lot less clutter in the main entry point.

The other thing I really didn’t like is the way you had to have this special ResourceDictionary called “StandardStyles.xaml“. If they truly are standard, what the hell are they doing in my app, and why aren’t they included in the framework. Also why are most of the styles in there commented out, and we have to uncomment them as we need them.

Magic Classes That Are Provided

I also didn’t like the fact that there are a bunch of classes provided which I have no idea whether I need them or not.

For example if you create a new Grid application you get this.

  • Common
    • BindableBase
    • BooleanNegationConverter
    • BooleanToVisibilityConverter
    • LayoutAwarePage
    • RichTextColumns
    • SuspensionManager

Now I know what a value converter is, so they are ok, but don’t things like “LayoutAwarePage” and “SuspensionManager” sound like framework issues to you? They sure do to me, again why are these classes in my codebase. Surely a LayoutAwarePage should be the defacto page for ANY WinRT application. You know we are supposed to think that the Surface is an iPad rival, yet last time I looked I could twist an iPad this way and that, and you can also do that with a Surface. So why isn’t the LayoutAwarePage the standard. By the same token since there is a suspension type of lifecycle in WinRT why is the SuspensionManager not in the class library.

Also what the heck is “RichTextColumns” do I need that, what does it do. Is it required for a GridView, and if so (yes I’ll say it again) why isn’t it in the framework.

Ok, I could find out, but when I start a new app, I would much prefer to see a clean slate really.

Early Days But

To my mind it just feels like it was rushed out the door, and feels very unpolished. Now I am a massive Microsoft fan boy, but I just felt let down by WinRT. As I say I will still be putting out this WinRT article soon, but it will likely be my one and only for a while.

Anyway those are just my thoughts, no one elses, many will likely disagree, which is fine.

WinRt

WinRT : Asynchronous code in SearchPane.SuggestionsRequested

As part of something a lot larger that I am currently working on I wanted to implement the Search charm logic in Windows 8.

Now being the model citizen that I am, I have read all the good technical bumpg around Windows 8, and I paid particular attention to the fact that we really need to keep the UI free, as anything more than 30/300ms (can’t recall which) on a touch system just feels broken.

So what does that mean? Well it means I have been a good chat and played nice and used Async/Await where needed. All good so far.

So now onto the Search charm. I obviously enabled this in the manifest file. Then I wrote the following code which I expected to work

sealed partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

    protected override async void OnLaunched(LaunchActivatedEventArgs args)
    {
        ....
        ....
        ....
        ....

        SetupSearch();
    }

    private async void OnSuspending(object sender, SuspendingEventArgs e)
    {
        var deferral = e.SuspendingOperation.GetDeferral();
        await SuspensionManager.SaveAsync();
        deferral.Complete();
    }

    private void SetupSearch()
    {
        var searchPane = SearchPane.GetForCurrentView();
        searchPane.SuggestionsRequested += searchPane_SuggestionsRequested;
        searchPane.ResultSuggestionChosen += searchPane_ResultSuggestionChosen;
    }

    void searchPane_ResultSuggestionChosen(SearchPane sender,
        SearchPaneResultSuggestionChosenEventArgs args)
    {
        MessageDialog dialog = new MessageDialog(string.Format("You picked {0}",args.Tag));
        dialog.ShowAsync();
    }

    async void searchPane_SuggestionsRequested(SearchPane sender,
        SearchPaneSuggestionsRequestedEventArgs args)
    {
        var suggestions = Enumerable.Range(1, 2).Select(x => new
        {
            Desc = string.Format("{0}_{1}", args.QueryText, x.ToString()),
            Id = x
        });

        //To simulate waiting on something more meaningful (such as a webservice etc etc)
        await Task.Delay(2000);

        var imageUri = new Uri("ms-appx:///Assets/search40.png");
        var imageSource = Windows.Storage.Streams.
              RandomAccessStreamReference.CreateFromUri(imageUri);
        args.Request.SearchSuggestionCollection.
              AppendSearchSeparator("Demo Suggestions");

        foreach (var suggestion in suggestions)
        {
            args.Request.SearchSuggestionCollection.AppendResultSuggestion(
                 "Suggestion",
              suggestion.Desc,
                suggestion.Id.ToString(),
                imageSource, "");
        }
    }
}

That looked fair enough to me. But when I ran this code I got this Exception

Most strange.

Turns out this is an issue for which there is a solution, that is just rather poorly documented. In fact it borrows a lot from the jQuery Deferred pattern (which you can read more about here)

So what is the solution. Well as I say WinRT has certainly borrowed from the jQuery Deferral / Promise idea. Where we ask for a Deferrable object, do some work, and then complete the Deferrable object.

So here is the code above refactored to use a WinRT Deferrable object. This technique can be used with most of the charms.

sealed partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

    protected override async void OnLaunched(LaunchActivatedEventArgs args)
    {
        ....
        ....
        ....
        ....

        SetupSearch();
    }

    private async void OnSuspending(object sender, SuspendingEventArgs e)
    {
        var deferral = e.SuspendingOperation.GetDeferral();
        await SuspensionManager.SaveAsync();
        deferral.Complete();
    }

    private void SetupSearch()
    {
        var searchPane = SearchPane.GetForCurrentView();
        searchPane.SuggestionsRequested += searchPane_SuggestionsRequested;
        searchPane.ResultSuggestionChosen += searchPane_ResultSuggestionChosen;
    }

    void searchPane_ResultSuggestionChosen(SearchPane sender,
        SearchPaneResultSuggestionChosenEventArgs args)
    {
        MessageDialog dialog = new MessageDialog(string.Format("You picked {0}",args.Tag));
        dialog.ShowAsync();
    }

    async void searchPane_SuggestionsRequested(SearchPane sender,
        SearchPaneSuggestionsRequestedEventArgs args)
    {
        var suggestions = Enumerable.Range(1, 2).Select(x => new
        {
            Desc = string.Format("{0}_{1}", args.QueryText, x.ToString()),
            Id = x
        });

        //FIXED CODE : Use args.Request.GetDeferral() / deferral.Complete

        var deferral = args.Request.GetDeferral();

        await Task.Delay(2000);

        var imageUri = new Uri("ms-appx:///Assets/search40.png");
        var imageSource = Windows.Storage.Streams.
                RandomAccessStreamReference.CreateFromUri(imageUri);
        args.Request.SearchSuggestionCollection.
                AppendSearchSeparator("Demo Suggestions");

        foreach (var suggestion in suggestions)
        {
            args.Request.SearchSuggestionCollection.AppendResultSuggestion(
                "Suggestion",
                suggestion.Desc,
                suggestion.Id.ToString(),
                imageSource, "");
        }

        deferral.Complete();
    }

}

As always here is a small demo project (requires Windows 8 / Visual Studio 2012)  : AsyncSearchSuggestionDemo.zip

Uncategorized

Reactive Command With Dynamic Predicates

As some of you know I have been a firm advocate and supporter of WPF for a long time now, and I still am. However one thing I have never been that keen on is the way the ICommand implementations that you typically see when writing VM code work. This includes RelayCommand / DelegateCommand and all ones similar to that.

The problem usual stems from the way the CanExecute is wired up to the CommandManager.RequerySuggested.

This does indeed enable the ICommand to work correctly, and any ICommandTarget objects will be disabled correctly when the CanExecute method is called. All ok so far.

The real problem comes with how the CanExecute predicate is called. This is typically called a lot, and under certain conditions such as mouse move, scroll and many more operations. Using the CommandManager.RequerySuggested is in fact very chatty.

Despite the chattyness of this approach, you can still get into a situation where the ICommand implementation doesn’t behave correctly, I have seen this under strange focus conditions.

So what is the solution. Well one approach is to manually raise the CanExecuteChanged event of ICommand instead of using the CommandManager.RequerySuggested approach. This is good and does solve the issue, but that means you are now in a situation where you need to know exactly when to raise the CanExecuteChanged event of ICommand. Thing is there may be occassions you just hadn’t thought of.

Is there another way…..Mmmm let me think, well yes there is. We can use the Reactive Extensions for this. In fact there is a whole library out there for MVVM based on the use of Reactive Extensions, its called Reactive UI (which is maintained by Paul Betts) which has a very similar idea to this blog post, but they are not quite the same.

What Paul Betts has done is to use the Reactive Extensions along with a ICommand to allow the ICommand implementation to start with a single IObservable<bool> that will raise the ICommand.CanExecuteChanged event. This is cool, but what I wanted was the ability to add arbitary predicates to the ICommand implementation, that could be added at any stage of the ICommand implementation lifecycle not just when you declared the ICommand.

Anyway the basic idea behind the code presented in this blog is that we use the Reactive Extensions to  come up with a combined IObservable<bool> stream for all combined predicates for the ICommand, and then use the current result of that to raise the Command.CanExecuteChanged event. The result of which is a very responsive ICommand, and it always works, no weird focus issues.

Anyway lets continue to look at the code shall we.

Here is the ReactiveCommand in its entirety. The real thrust of it, is the AddPredicate method, which ensures we always have a combined predicate which will make the ICommand work correctly

public interface IReactiveCommand : ICommand
{
    IObservable<object> CommandExecutedStream { get; }
    IObservable<Exception> CommandExeceptionsStream { get; }
    void AddPredicate(IObservable<bool> predicate);
}

public class ReactiveCommand : IReactiveCommand, IDisposable
{
    private Subject<object> commandExecutedSubject = new Subject<object>();
    private Subject<Exception> commandExeceptionsSubjectStream = new Subject<Exception>();
    private List<IObservable<bool>> predicates = new List<IObservable<bool>>();
    private IObservable<bool> canExecuteObs;
    private bool canExecuteLatest = true;
    private CompositeDisposable disposables = new CompositeDisposable();

    public ReactiveCommand()
    {
        RaiseCanExecute(true);
    }

    public ReactiveCommand(IObservable<bool> initPredicate, bool initialCondition)
    {
        if (initPredicate != null)
        {
            canExecuteObs = initPredicate;
            SetupSubscriptions();
        }
        RaiseCanExecute(initialCondition);
    }

    public void AddPredicate(IObservable<bool> predicate)
    {
        disposables.Dispose();
        predicates.Add(predicate);
        this.canExecuteObs = this.canExecuteObs.CombineLatest(
                predicates.Last(), (a, b) => a && b).DistinctUntilChanged();
        SetupSubscriptions();
    }

    bool ICommand.CanExecute(object parameter)
    {
        return canExecuteLatest;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        commandExecutedSubject.OnNext(parameter);
    }

    public IObservable<object> CommandExecutedStream
    {
        get { return this.commandExecutedSubject.AsObservable(); }
    }

    public IObservable<Exception> CommandExeceptionsStream
    {
        get { return this.commandExeceptionsSubjectStream.AsObservable(); }
    }

    public void Dispose()
    {
        disposables.Dispose();
    }

    protected virtual void RaiseCanExecuteChanged(EventArgs e)
    {
        var handler = this.CanExecuteChanged;

        if (handler != null)
        {
            handler(this, e);
        }
    }

    private void RaiseCanExecute(bool value)
    {
        canExecuteLatest = value;
        this.RaiseCanExecuteChanged(EventArgs.Empty);
    }

    private void SetupSubscriptions()
    {

        disposables = new CompositeDisposable();
        disposables.Add(this.canExecuteObs.Subscribe(
            //OnNext
            x =>
            {
                RaiseCanExecute(x);
            },
            //onError
            commandExeceptionsSubjectStream.OnNext
        ));
    }
}

I hope this is easy enough to understand. The next thing to look at is any example usage of this, which is as follows:

public class ViewModel : INPCBase
{
    private string title;
    private bool hasStuff;

    public ViewModel()
    {
        IObservable<bool> initPredicate = this.ObserveProperty(x => x.Title)
                 .StartWith(this.Title).Select(x => !string.IsNullOrEmpty(x)); ;
        IObservable<bool> predicate = this.ObserveProperty(x => x.HasStuff)
                 .StartWith(this.HasStuff);
        SomeCommand = new ReactiveCommand(initPredicate, false);
        SomeCommand.AddPredicate(predicate);
        SomeCommand.CommandExecutedStream.Subscribe(x =>
            {
                MessageBox.Show("Command Running");
            });
    }

    public ReactiveCommand SomeCommand { get; set; }

    public string Title
    {
        get
        {
            return this.title;
        }
        set
        {
            RaiseAndSetIfChanged(ref this.title, value, () => Title);
        }
    }

    public bool HasStuff
    {
        get
        {
            return this.hasStuff;
        }
        set
        {
            RaiseAndSetIfChanged(ref this.hasStuff, value, () => HasStuff);
        }
    }

}

This code makes use of the following helper code to pluck out an IObservable<T> from a property. Which was largely taken from Keith Woods blog

public static class ObservableExtensions
{
    public static IObservable ObserveProperty<T, TValue>(
        this T source,
            Expression<Func<T, TValue>> propertyExpression
    )
        where T : INotifyPropertyChanged
    {
        return source.ObserveProperty(propertyExpression, false);
    }

    public static IObservable ObserveProperty<T, TValue>(
        this T source,
        Expression<Func<T, TValue>> propertyExpression,
        bool observeInitialValue
    )
        where T : INotifyPropertyChanged
    {
        var memberExpression = (MemberExpression)propertyExpression.Body;

        var getter = propertyExpression.Compile();

        var observable = Observable
            .FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                h => new PropertyChangedEventHandler(h),
                h => source.PropertyChanged += h,
                h => source.PropertyChanged -= h)
            .Where(x => x.EventArgs.PropertyName == memberExpression.Member.Name)
            .Select(_ => getter(source));

        if (observeInitialValue)
            return observable.Merge(Observable.Return(getter(source)));

        return observable;
    }

    public static IObservable ObservePropertyChanged(this T source)
        where T : INotifyPropertyChanged
    {
        var observable = Observable
            .FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                h => new PropertyChangedEventHandler(h),
                h => source.PropertyChanged += h,
                h => source.PropertyChanged -= h)
            .Select(x => x.EventArgs.PropertyName);

        return observable;
    }

    public static IObservable ObserveCollectonChanged(this T source)
        where T : INotifyCollectionChanged
    {
        var observable = Observable
            .FromEvent<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                h => new NotifyCollectionChangedEventHandler(h),
                h => source.CollectionChanged += h,
                h => source.CollectionChanged -= h)
            .Select(_ => new Unit());

        return observable;
    }

    public static IObservable ObserveCollectonChanged(
         this T source, NotifyCollectionChangedAction collectionChangeAction)
                where T : INotifyCollectionChanged
    {
        var observable = Observable
            .FromEvent<NotifyCollectionChangedEventHandler, NotifyCollectionChangedEventArgs>(
                h => new NotifyCollectionChangedEventHandler(h),
                h => source.CollectionChanged += h,
                h => source.CollectionChanged -= h)
            .Where(x => x.EventArgs.Action == collectionChangeAction)
            .Select(_ => new Unit());

        return observable;
    }
}
WinRt

WinRT : How to communicate with WebView Javascript from C# and Vice Versa

The other day I was contacted by one of the fellow Xaml Disciples (who have been dormant for a long time, but hey ho), who was asking how he might
determine if some audio within a web site was playing or not. I thought he problem could be solved using the WebView available
in WinRT. Turns out I didn’t get what his actual problem was, and this did not help him. I did however try something out before I answered him, which
was how to communicate with the WebView hosted HTML/JavaScript from c# and vice versa.

I thought that may make a semi-useful blog post. So I have provided a dead simple example, the c# code will try and change the FontSize of a DIV
within the hosted HTML content by calling a JavaScript function in the hosted HTML content. The JavaScript will then double the incoming FontSize and use
it for the DIV, and at the same time tell the c# what the doubled size is via a callback into the c3 code. Simple requirement really

It all starts with the markup which is shown in its entirety below

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Border Background="{StaticResource ApplicationPageBackgroundThemeBrush}" BorderBrush="White"
		BorderThickness="4" Height="400" Width="640" Padding="10">
        <StackPanel>
            <StackPanel.Resources>
                <Style x:Key="RefreshAppBarButtonStyle" TargetType="ButtonBase"
			BasedOn="{StaticResource AppBarButtonStyle}">
                    <Setter Property="AutomationProperties.AutomationId" Value="RefreshAppBarButton"/>
                    <Setter Property="AutomationProperties.Name" Value="Refresh"/>
                    <Setter Property="Content" Value=""/>
                </Style>
            </StackPanel.Resources>
            <WebView x:Name="webView" Height="300" Width="600"/>
            <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="10">
                <Button x:Name="font25" Content="25px" Click="Change25_Click"/>
                <Button x:Name="font40" Content="40px" Click="Change40_Click"/>
                <Button x:Name="font60" Content="60px" Click="Change60_Click"/>
                <Button x:Name="reset" Content="Reset" Click="Reset_Click"/>
            </StackPanel>
        </StackPanel>
    </Border>
</Page>

Nothing fancy there, just a WebView control and a few buttons to change the FontSize of the DIV

So lets have a look at the c# side of things. Here it is in its entirety

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;

namespace App1
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            webView.ScriptNotify += webView_ScriptNotify;
        }

        async void webView_ScriptNotify(object sender, NotifyEventArgs e)
        {
            var jsScriptValue = e.Value;
            MessageDialog msg = new MessageDialog(jsScriptValue);
            var res =  await msg.ShowAsync();

        }

        private const string htmlFragment =
                    "<html><head><script type='text/javascript'>" +
                    "function doubleIt(incoming){ " +
                    "  var intIncoming = parseInt(incoming, 10);" +
                    "  var doubled = intIncoming * 2;" +
                    "  document.body.style.fontSize= doubled.toString() + 'px';" +
                    "  window.external.notify('The script says the doubled value is ' + doubled.toString());" +
                    "};" +
                    "</script></head><body><div id='myDiv'>I AM CONTENT</div></body></html>";

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            webView.NavigateToString(htmlFragment);
        }

        private void Reset_Click(object sender, RoutedEventArgs e)
        {
            webView.NavigateToString(htmlFragment);
        }

        private void Change25_Click(object sender, RoutedEventArgs e)
        {
            webView.InvokeScript("doubleIt", new string[] { "25" });
        }

        private void Change40_Click(object sender, RoutedEventArgs e)
        {
            webView.InvokeScript("doubleIt", new string[] { "40" });
        }

        private void Change60_Click(object sender, RoutedEventArgs e)
        {
            webView.InvokeScript("doubleIt", new string[] { "60" });
        }

    }
}

Calling JavaScript from c#

This is done using the WebView.InvokeScript() method, where it expects a name of a function, and a string[] for the arguments

Calling c# from JavaScript

This is slightly trickier as you need to carry out the following 3 steps

Step 1 : Hook up the WebView.ScriptNotify event

Step 2 : Use the result of the NotifyEventArgs.Value from Step 1

Step 3 : Get the WebView to actually call the ScriptNotify c# event, which is done via this bit of code:

window.external.notify(..)

NOTE

WinRT makes a big point out of the fact that the WebView control is a regular WinRT control that can be treated as any other element
such as applying Transforms etc etc, while this is true (I have seen the demos/videos/screenshots). However it seems one area has been missed (at least in Windows 8.0 that
I am currently using), which is that the WebView seems to be the top most element. Try the XAML below and see what you think

<Page
    x:Class="App1.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App1"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Grid Background="Black" Grid.Row="0">
            <StackPanel Orientation="Horizontal"  Margin="20">
                <ComboBox Width="150">
			<ComboBoxItem Content="hello1"/>
			<ComboBoxItem Content="hello2"/>
			<ComboBoxItem Content="hello3"/>
			<ComboBoxItem Content="hello4"/>
			<ComboBoxItem Content="hello5"/>
			<ComboBoxItem Content="hello6"/>
			<ComboBoxItem Content="hello7"/>
			<ComboBoxItem Content="hello8"/>
			<ComboBoxItem Content="hello9"/>
			<ComboBoxItem Content="hello10"/>
			<ComboBoxItem Content="hello11"/>
			<ComboBoxItem Content="hello12"/>
			<ComboBoxItem Content="hello13"/>
			<ComboBoxItem Content="hello14"/>
		</ComboxBox>
                <Button Content="Reset" Margin="10,0,0,0" Height="45" />
            </StackPanel>
        </Grid>
        <WebView Grid.Row="1" HorizontalAlignment="Stretch"
                 VerticalAlignment="Stretch" Margin="10,0,10,10" />

    </Grid>

</Page>

For me the ComboBox popup goes behind the WebView, a tad annoying, and for me makes the WebView pretty unworkable.

As always here is a small demo project :

Demo project.zip