Category Archives: programming windows store apps

Support readiness before putting the winjs app out for trial

Published April 15, 2014 1:08 pm

Before deploying the current app under development for trial, I was thinking about app support. We needed:

  1. ability to quickly get the error information from the user.
  2. ability to get unhandled exception detail in case App crashes.

Let’s talk about first. Across the app codebase, Util method handleError is used to display error to the user. This method used the standard Windows.UI.Popups.MessageDialog. The solution was to add a ‘copy’ command to the dialog – to enable user to copy error to clipboard. The code for this is quite straight forward by going through some pages in msdn.

function handleError(error)
{
    assert.instanceOf(error, Error);
    var message = getDisplayErrorMessage(error);
    var popups = Windows.UI.Popups;
    var dialog = new popups.MessageDialog(message);
    dialog.commands.append(new popups.UICommand('Copy', copyCommand));
    dialog.commands.append(new popups.UICommand('Close'));
    dialog.defaultCommandIndex = 1;
    return dialog.showAsync();

    function copyCommand(event)
    {
        copyToClipboard({ message: message, stack: error.stack });
    }

    function copyToClipboard(data)    
    {
        assert.isObject(data);
        var dt = Windows.ApplicationModel.DataTransfer;
        var dp = new dt.DataPackage();
        dp.requestedOperation = dt.DataPackageOperation.copy;
        dp.setText(JSON.stringify(data));
        dt.Clipboard.setContent(dp);
    }
}

getErrorDisplayMessage is implementation specific. In our case, it goes through all innerError and error contextual detail – to form a display message. For example: every error related to a backend service call includes requestId guid. This enables support to trace down the faulting service request.

Regards second thing: WinJS.Application.onerror or Windows.onerror provides the hook to get to the unhandled exception. First tried solution was to copy the unhandled exception to clipboard through this hook. What I found – the error is copied to the clipboard but clipboard is cleared after the app exits. Hence, this solution does not work.

After little bit of bing, I found a post – which mentioned that the apphost source logs an administrative event in windows event log when the app crashes. Quickest way to get exception details to clipboard is –

  1. win+x key,
  2. selection event viewer,
  3. go to custom views->administrative events,
  4. right click the event with source ‘apphost’,
  5. copy->copy details as text.

Steps are long but for the time being – they looked good enough. event has all the details including exception fields and stack. Other solution is to log details to disk and add feature in app to share/copy to clipboard the data about last app crash. This solution looked costly for now.

With this, the app is support ready. How do you handle errors in your app and ask user to share the error info with you?

Adding a placeholder page in WinJS App

Published March 13, 2014 11:14 am

If you are building a winjs app – you may hit the need for a placeholder page. What I mean by placeholder page? Examples: initial login page. Once user has logged in, it should not show up in the navigation history; that is user must not be able to navigate it using back button on the next page.

This leads to obvious question – how do I remove a page from navigation history or how do I navigate to a page without adding it to <code>WinJS.Navigation.history</code>.

I made a failed attempt by resetting <code>WinJS.Navigation.history.backStack</code> when the navigate promise completes for the next page. This does not work since next page is already rendered by then and next page back button is visible. Clicking on the back button there does not do anything. but it must not be visible.

Next – google pointed to solution here by Kraig. This one line of code is the solution and needs to be placed when navigating away from the initial placeholder page like login page.

    WinJS.Navigation.history.current.initialPlaceholder = true;
    WinJS.Navigation.navigate('/pages/home/home.html');

dispatchEvent method invocation fails with error ‘java script invalid object’

Published February 18, 2014 9:41 am

This was kind of obscure error in a WinJS application yesterday. The object is non-null, mixed with WinJS.UI.DOMEventMixin but still obj.dispatchEvent(...) fails with the error ‘java script invalid object’. After little bit of pondering, It turned out to be an issue with stubbing done by binding. This object was being set to dataSource property of a custom control. This property is an observable property of the control. The stubbing for making the property observable was causing the error.

The solution was to unwrap the object before invoking the method.

    var obj = WinJS.Binding.unwrap(obj);
    obj.dispatchEvent('myevent', { message: 'my message' });

Handling data download in windows store application

Published February 14, 2014 1:43 pm

We have one app that downloads data as user moves through pages. There were few observations as I went through fixing issues there.

General gyan about adding support for network in the app can be found here; it is worth a skim; not all may apply for every app.

In our app, I need to handle mainly these things:

  1. download failure error handling – if the network connection is not available, or the http client async api calls throws or return any error.
  2. async download task cancellation – when the user moves between pages in the app, download async task for the previous page need to be canceled.

Network connection not available

The app want to display a clean error message to the user – “Internet connection is not available.” after determining conclusively that internet access is not there. The code snippet below does the job.

 
    using Windows.Networking.Connectivity;
    private bool CheckInternetAccess()
    {
        ConnectionProfile profile =
            NetworkInformation.GetInternetConnectionProfile();

        var level = profile != null ? profile.GetNetworkConnectivityLevel() : NetworkConnectivityLevel.None;
        if (level >= NetworkConnectivityLevel.InternetAccess)
        {
            // We have Internet, all is golden
            return true;
        }

        return false;
    }

    bool isMessageBoxActive;
    using Windows.UI.Popups;
    public async Task ShowMessage(string message)
    {
        if (this.isMessageBoxActive)
            return;

        this.isMessageBoxActive = true;
        MessageDialog dialog = new MessageDialog(message);
        await dialog.ShowAsync();
        this.isMessageBoxActive = false;
    }

    bool internetOk = this.CheckInternetAccess();
    if (!internetOk)
        this.showMessage("Internet connection is not available");

This works for displaying one time error message to the user. Since in my case, there was no need to keep a check if the connectivity goes down/up, I have not used NetworkStatusChanged event.

HttpClient.GetAsync api error handling

Next the api call to download the data GetAsync need to be cancelable and it’s exception & errors need to be handled. To cancel,  api overload taking a cancellationToken can be used. CancellationTokenSource (cts) provides the cancellation token which can be passed to the api. To cancel the task, cts.Cancel() needs to be called. To understand – How to cancel async task – this msdn topic will help.

The code below handles exception and errors.

    public async Task LoadData(CancellationToken cancellationToken)
    {
        if (this.data != null)
            return;

        bool internetOk = this.CheckInternetAccess();
        if (!internetOk)
        {
            var message = Singletons.ResourceLoader.GetString("InternetNotAvailable");
            throw new DataLoadException(message);
        }

        HttpClient client = new HttpClient();
        using (client)
        {
            HttpResponseMessage response = null;
            try
            {
                response = await client.GetAsync(this.dataUrl, cancellationToken);
            }
            catch (TaskCanceledException)
            {
                throw;
            }
            catch (Exception e)
            {
                var m = Singletons.ResourceLoader.GetString("DataDownloadException");
                var fm = string.Format(m, this.Title, e.Message);
                throw new DataLoadException(fm);
            }

            if (!response.IsSuccessStatusCode)
            {
                var message = Singletons.ResourceLoader.GetString("DataDownloadFailed");
                var formattedMessage = string.Format(message, this.Title, (int)response.StatusCode);
                throw new DataLoadException(formattedMessage);
            }

            try
            {
                var content = await response.Content.ReadAsStringAsync();
                this.data = DataParser.Parse(content);
            }
            catch (Exception)
            {
                var m = Singletons.ResourceLoader.GetString("DataParsingFailed");
                var fm = string.Format(m, this.Title);
                throw new DataLoadException(fm);
            }
        }
    }

The calling code provides the cancellation token and calls cancel during code paths where the async task needs to be canceled.

    private CancellationTokenSource dataLoadOperationCts;
    private void Unload_handler()
    {
        if (this.dataLoadOperationCts != null)
        {
            this.dataLoadOperationCts.Cancel();
            this.dataLoadOperationCts = null;
        }
    }

    private async void initialize()
    {
        this.dataLoadOperationCts = new CancellationTokenSource();

        // need to trigger download of data. 
        ...
        Exception error = null;
        try
        {
            await item.LoadData(this.dataLoadOperationCts.Token);
        }
        catch (DataLoadException err)
        {
            error = err;
        }
        catch (TaskCanceledException)
        {
            // do nothing
        }

        if (error != null)
            await this.ShowMessage(error.Message);
    }

The LoadData helper method raises DataLoadException with app friendly error message which are then caught and handled by the UI code. DataLoadException and Singletons class are not included in the code listing but they are kind of obvious.

Few more things:

  1. Unit testing was important here. There are code paths that can not be reached easily. I have to exercise the code path by throwing exception by hand in code or using slow network where download took time & canceling midway when the GetAsync call did not yet complete or disconnecting the network. For slow network, I have used the slow 2g mobile internet by sharing it using “internet sharing” feature on mobile.
  2. Using Xxxasync methods on http client is key. Don’t try to read the stream returned using GetStreamAsync and then use sync methods like TextReader.ReadToEnd. That will result in sync read and responsiveness issues in app.
  3. Need to handle all exception thrown by async api or unhandled exception will cause app to crash.
  4. I did a brief search for System.Net.WebClient vs System.Net.Http.HttpClient after finishing the work. It looked like HttpClient is newer api entry.

Every app has different set of network access needs. HTH. Share your learnings through comments.

Using WinJS.Binding.List to update the list view

Published December 3, 2013 1:06 pm

WinJS.UI.ListView is the most used control in WinJS library. At the beginning, you typically start with static List views. In such List Views, data does not change after it is bound. You may have to sort or group data which can be achieved using createSorted or createGrouped methods on List. You can order the items, group the items, and order the groups using these methods. If you follow some of the msdn listview samples, it is sort of clear. (Note: not all samples needs to be followed to get hang of list view. Some of them like custom data source, incremental loading are advanced scenarios).

When you working with dynamic data, list view updates as user interacts with the list view. Examples:

  1. User can right click a item, and delete it using contextual app bar command.
  2. User clicks/taps an item. The item is either removed or updated.

List view elements sort order and grouping needs to be maintained after the item change or list changes. In this post, let’s look into (2). I will try to cover (1) in another post. To go over this, let’s take a simple problem of displaying list of todo tasks.

  1. The tasks should be displayed in two  groups – ‘todo’ and ‘done’ groups.
  2. When a task is clicked or tapped in the todo group – it is moved to ‘done’ group.
  3. ‘done’ group should maintain only the latest 5 done tasks. oldest task gets off the list when list grows beyond 5 tasks.

my-tasks-1With this, Let’s look at the HTML

<div id="todoListView" data-win-control="WinJS.UI.ListView"
    data-win-bind="winControl.itemDataSource: items.dataSource; winControl.groupDataSource: items.groups.dataSource"
    data-win-options="{
      itemTemplate: select('#todoItemTemplate'),
      groupHeaderTemplate: select('#groupHeaderTemplate'),
      selectionMode: 'none', swipeBehavior: 'none', tapBehavior: 'invokeOnly' }">
</div>
  1. list should have tapBehavior set to invokeOnly to enable click/tap.
  2. itemTemplate and groupHeaderTemplate are set which is kind of obvious.
  3. this snippet binds itemDataSource and groupDataSource in html. If you don’t have view model (MVVM) separate in your code, you may set it in the .js file.

Let’s look at the sample data.

var data = [
    { status: 'todo', title: 'wake up' },
    { status: 'todo', title: 'brush your teeth' },
    { status: 'todo', title: 'take bath' },
    { status: 'todo', title: 'do yoga' },
    { status: 'todo', title: 'take breakfast' },
    { status: 'todo', title: 'check email' },
    { status: 'todo', title: 'check facebook' },
    { status: 'todo', title: 'check stackoverflow forum' },
];

We will sort the list using the sort key <status, finishTime>. finishTime will be added whenever user taps the item. todo status is sorted before done status. finishTime is sorted in descending order. This way – all done items are order towards end of the list. Further, If any item is to be dropped, it is at the end of the list.

 

    function compareStatus(t1, t2)
    {
        if (t1 == t2)
            return 0;
        else if (t1 == 'todo')
            return -1;
        else
            return 1;
    }

    function compareFinishTime(d1, d2)
    {
        if (d1 == undefined && d2 == undefined)
            return 0;
        // treat unfinished task ahead in sort order
        else if (d1 == undefined)
            return -1;
        else if (d2 == undefined)
            return 1;
        else
        {
            var t1 = d1.getTime(), t2 = d2.getTime();
            // treat recently finished task ahead in sort order
            if (t1 > t2)
                return -1;
            else
                return 1;
        }
    }

    var sortedList = list.createSorted(function compare(i1, i2)
    {
        var c1 = compareStatus(i1.status, i2.status);
        if (c1 != 0)
            return c1;
        var c2 = compareFinishTime(i1.finishTime, i2.finishTime);
        return c2;
    });

Further, we use createGrouped to group the sorted items and order the groups.

    this.items = sortedList.createGrouped(function groupKey(item)
    {
        return item.status;
    },
    function groupData(item)
    {
        return { title: item.status };
    }, 
    function groupSorter(g1, g2)
    {
        // keep todo items group b4 'done' items group
        if (g1 == g2)
            return 0;
        else if (g1 == 'todo')
            return -1;
        else 
            return 1;
    });

Now, to move the item from ‘todo’ group to ‘done’ group – we can change the item in the iteminvoked handler and notify the list for item mutation using notifyMutated method. Once notified, list sorted and grouped projection will update themselves. It will reflect in the bound list view.

 
registerItemInvokedHandler: function registerItemInvokedHandler()
{
    function oniteminvoked(event)
    {
        var index = event.detail.itemIndex;
        var item = this.viewModel.items.getAt(index);
        // click on 'done' tasks should be noop. 
        if (item.status == 'done')
            return;
        item.status = 'done';
        item.finishTime = new Date();
        this.viewModel.items.notifyMutated(index);
        // schedule removal for later using setImmediate
        WinJS.Promise.timeout().then(removeIfReqd.bind(this));
    }

    function removeIfReqd()
    {
        var count = 0;
        var items = this.viewModel.items;
        for (var i = items.length; i > 0; i--)
        {
            var item = items.getAt(i - 1);
            if (item.status == 'todo')
                break;
            count++;
        }

        // remove only if more than 5 'done' items
        if (count > 5)
            items.splice(items.length - 1, 1);
    }

    todoListView.addEventListener('iteminvoked', oniteminvoked.bind(this));
},

my-tasks-3* Note the code above references items from the viewModel. That needs to be modified to reference items as per your code.

This way – we saw in this post – how createSorted, createGrouped along with notifyMutated – can be used to build a dynamic list view.

Uploading image to the web service in WinJS application

Published November 27, 2013 1:07 pm

It is very likely that you need to have functionality to pick single or multiple image(s) and upload to your web service in your winjs windows store application. First, we will go through single image case. I have seen image pick & upload experience very often in facebook and google plus web client. Both of the web clients have ‘native’ experience for picking & uploading image(s). What I mean by native is that they have custom built experience that fits into their overall user experience. You will need to build a custom image select control that will do some or all of these:

  1. Launch picker – On click, launch windows file picker initialized to pick image file.
  2. Display preview – of the selected image. If no image is selected, display a placeholder image.
  3. Store file object – keep the file object picked by the user until it is submitted to the web service.
  4. View – you may need to show the preview of the image that already exists at the web service.
  5. delete command – context menu or other way to let user delete the uploaded image.
  6. download progress – related to (4), show progress while the image is downloading from the web service.
  7. show error – related to (4), show error if the image download fails.
  8. send command to service – to delete or upload the image
  9. show progress of command sent to the service
  10. reduce the size of the picked image before upload to the service.

The above is top down view of all the things related to uploading image in your winjs client. Building a custom control in winjs is a good topic on its own. We will not go over it in this post. This msdn blog post is a good start for building custom winjs control in your project.

Let’s get started.
html:

<img class="select-image" src="images/placeholder.png" />

js:

 
    var page = WinJS.UI.Pages.define('/pages/page1/page.html', 
    {
        ready: function onready(element, options)
        {
             ...
             var img = element.querySelector('.select-image');
             img.addEventListener('click', this.onclick.bind(this));
        }),
        onclick: function onclick()
        {
            var self = this;
            var img = this.element.querySelector('.select-image');
            this.pickSingleImage().then(function onpicksinglefile(file)
            {
                if (!file)
                    return;

                // set the blob to img.src for preview
                var imageUrl = URL.createObjectURL(file, { oneTimeOnly: true });
                img.src = imageUrl;
                // keep file object for upload later
                self.selectedFile = file;
            });
        },
        // launches file open picker initialized to pick an image
        pickSingleImage: function pickSingleImage()
        {
            // Verify that we are currently not snapped, or that we can unsnap to open the picker
            var currentState = Windows.UI.ViewManagement.ApplicationView.value;
            if (currentState === Windows.UI.ViewManagement.ApplicationViewState.snapped &&
                !Windows.UI.ViewManagement.ApplicationView.tryUnsnap())
            {
                // Fail silently if we can't unsnap
                return WinJS.Promise.timeout();
            }

            // Create the picker object and set options
            var openPicker = new Windows.Storage.Pickers.FileOpenPicker();
            openPicker.viewMode = Windows.Storage.Pickers.PickerViewMode.thumbnail;
            openPicker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.picturesLibrary;
            // Users expect to have a filtered view of their folders depending on the scenario.
            // show file types that are accepted by your service 
            openPicker.fileTypeFilter.replaceAll([".gif", ".jpg", ".jpeg"]);

            // Open the picker for the user to pick a file
            return openPicker.pickSingleFileAsync();
        },
        // returns a promise that completes on upload of the file to the url.
        uploadBlob: function uploadBlob(url, file)
        {
            var data = MSApp.createFileFromStorageFile(file);
            var xhrOptions = {
                type: 'put', // this may be post if your web service expects http post
                url: url,    // url for the web service
                headers: {
                    'Content-Type': 'image/jpeg',
                    'Content-Length': data.size,
                    // TODO - add any other headers that service may expect
                },
                data: data,
            };

            return WinJS.xhr(xhrOptions);
        },

The code above is more or less self explanatory. Few notes:

  1. uploadBlob needs to be invoked by other function when image is to be uploaded.
  2. For uploading image to azure blob, upload code will look similar. you can refer this post.

There we are. Current code will allow to pick, preview and upload an image file to your web service.

It does not cover all the 1-10 things listed above yet. Did your app need it?

Saving and restoring page state in a WinJS application

Published November 15, 2013 1:39 pm

When building a winjs application with multiple pages, there is high chance that you need to save and restore page state of some of the page(s).

First – what is page state and why it needs to be saved & restored? Let’s take few example cases.

  1. User inputs some data provided in a form page. When the form page is navigated back, form page needs to be filled with the same data; not lose data.
  2. Page contains a list view with multiple items; user scrolls to reach an item and clicks it to traverse to the item detail page. When user navigates back, list view’s scroll position should not be reset.
  3. Add another case for case (2). application is suspended when on the item detail page, restored during next activation and start on item details page. In such case also, the listview scroll position should not be lost when navigating back to the list view page.

How to handle this?

In a WinJS application, each page is re-initialized when navigated back. ready event handler is called each time a page is navigated. Hence, to keep the page in the same state – it’s state needs to be saved and restored. WinJS library provides WinJS.Application.SessionState object. It is serialized and de-serialized across application suspension by the library. The page state needs to be saved and restored to/from session state object.

What the code looks like? Let take the case (2).
Initializing, and restoring the scrollPosition state on the list view

 
    var sessionState = WinJS.Application.sessionState;
    ready: function onready(element, options)
    {
        ...
        if (!sessionState.itemList)
            sessionState.itemList = {};
        else if (sessionState.itemList.scrollPosition)
        {
            WinJS.Promise.timeout().then(function ()
            {
                listView.winControl.scrollPosition = sessionState.itemList.scrollPosition;
            });
        }
    },

Saving the scrollPosition state when navigating to the item detail page. The code below is doing that in the iteminvoked handler.

 
    listView.winControl.addEventListener('iteminvoked', function (event)
    {
        var item = this.viewModel.items.getAt(event.detail.itemIndex);
        sessionState.itemList.scrollPosition = textListView.winControl.scrollPosition;
        WinJS.Navigation.navigate('/pages/itemDetail/page.html', { item: item });
    }.bind(this));

That’s it. Few comments before closing.

  1. It will be good practice to keep separation between the state for each page. Hence, the code above saves the scrollPosition state for the itemList page under itemList property in session state object.
  2. The state is restored typically in the ready handler.
  3. The state needs to be saved prior to the navigation to the next page.
  4. scrollPosition is restored under a setImmediate call. otherwise, it does not get restored.

HTH.

WinJS 101

Published September 25, 2013 1:47 pm

Last couple of months has been heads down into our next app; The app is more involved app with authentication, backend service etc. I have not been able to find time to write blog. Today, I thought of resurrecting again. Here is what we are going to do. We will go over WinJS over next set of posts – as a winjs 101 for developer.

WinJS 101 for developer will be as close to code as possible. It is not meant to be executive summary. It is meant to be developer summary; a dev to dev talk/share – to help you jump start on this. If you are developer, who is starting because a) your current project needs it b) you want to remain updated of windows app development c) you want to get on to html/css/javascript since they are open and skill will be valuable on other platforms. It is likely that the post might help you. At the very least, it is an attempt with that intent. Let’s get started.

winjs-lib-002What is WinJS – well, it is windows javascript library. Like you have underscore.js, backbone.js – various javascript libraries, it is a javascript library meant for developing windows modern (aka metro) applications. When you open a new winjs based windows store application project in VS express 2012, you will find reference to winjs lib in solution explorer – like you used to find default reference to few net assemblies e.g. system in your .net projects. Your curiosity will certainly expand the node and you will find couple of these files there.

ui-dark.css/ui-light.css : css provides the way to declaratively style a html web page. css is available to style winjs applications. This file contains the default style rules for the windows controls. MSDN documentation of the WinJS controls will document the css classes that can be used to style them. For example – refer styling of listview control here. Typical web developer will not need introduction to css. If you are not a typical web developer, css introduction here helped me in past. Do not try to go through this file at beginning, it might be intimidating. It is like seeing disassembly of a .net assembly. Ctrl+f in this file will be of most help during first few days when documentation does not help getting to css classes for a winjs control.

base.js: In simply terms, this is the non-ui part of the winjs lib. Winjs library provides basic functions like WinJS.Class.define/derive: to define a class (using javascript prototype underneath), WinJS.Namespace.define: to organize code in namespaces (using simply dynamic javascript  object underneath) albeit there is no native thing called namespace in javascript, WinJS.Binding.List: one of the first class that you will get exposed; it is used as dataSource for winjs controls like ListView and FlipView, WinJS.Application namespace: apis/events for app start/suspend, session and setting mgmt. you will see reference to this mostly in default.js in your project. Note: that winrt apis* are natively accessible to winjs application and not part of the winjs lib. WinJS library provides added functionality to support winjs based application development. For winrt apis example: refer Windows.Storage.FileIO: it provides apis to read/write files. For all windows(aka winrt) api for all windows store apps – refer here. These can be used in windows store app written in javascript or any other supported language like c#, c++ etc.

*winrt api: winrt apis are referred as windows apis that are available to a windows store app, written any language of choice – c#, javascript, c++ etc. It is not a new/latest version of .net frameworks. It is a new framework altogether meant for windows store (modern) app development. This is a one line intro to winrt which is a longer  discussion otherwise.

ui.js: this is the ui part of the wijs lib. All html 5 controls (rather all documented to be supported by IE) can be used in winjs app. There are subtle differences in support when used in native modern app vs IE. At meta level, you can think of using html/DOM to build UI without getting into details at the onset. If you are web developer, you get to leverage all your knowledge of native html controls; listing of all controls here will make you happy.

ui.js provides additional ui controls apart from native html – like ListView, FlipView and more. There controls are rendered below a html div, written in javascript and styled using css. Not sure what that means – use debug->windows->DOM Explorer->select element in VS, and explore the html/css below a list view in your application. you will find that WinJS ListView control renders itself by spitting html in the DOM.

There is lot more under WinJS.UI namespace. Many of the controls like HubControl, SearchBox are coming windows 8.1. ListView, DatePicker, TimePicker, Flyout, AppBar has been the frequently used controls in my case. Again, like in case of base.js – this is not all. All other windows (aka winrt) controls – like Windows.UI.Popups.MessageDialog – are available to javascript and other languages like c#, c++.

Going back to our winjs lib node in picture above, you will find string resource files below en-us node. ui-dark and ui-light.css provides different style for light and dark theme. your application will use only one of them.

we have not yet finished talking about the other files in the a typical winjs project. There will be other things like data-win-control, data-win-options in html that won’t look like html attributes; a typical page in winjs app will be a Winjs PageControl defined using WinJS.UI.Pages.define(); javascript for the page needs to be organized little differently than its done for typical web pages. We will talk about these next time.

Before we close on this: Why WinJS? You will the right person to make the choice for your project. I will share few of my observations:

  1.  Are you a web developer that have sound html/css/js skills and need to code a windows store app? WinJS based application development will surely help to leverage your skills. At the same time, do not think you can get around without  any additional learning curve. There are windows specific nuances. but again, you will certainly have better jumpstart here than in going with c# and xaml.
  2. Are you are developer that have sound c#, xaml skills? yes – then certainly, windows provides default path of using xaml & c#. That will align well and give you good jumpstart. Should you think even once of learning html/js/css way of building the windows store app? Ask yourself do you want to get exposed to html/js/css. These skills are likely more transferable to other web/mobile development platforms. They might help you in the long run and good to have these skills in your arsenal even if you are a old timer solid dev. At the same time, do expect a learning curve of 6 month even if you are a Pro in c#, xaml, ms technologies; this is assuming that you have no exposure to css/html/js.
  3. If you already have sound html/css/js knowledge – using this library do help for windows store app dev.
  4. html/css/js skills are transferable to other web/mobile platforms. This will also come with disclaimer that winjs apis or windows api knowledge development will be key and require investment of time. This knowledge won’t be directly transferable to other platforms.
  5. if you are building application that falls in integration category – what I mean, the application falls in category of building a native windows experience for one or more web services. json/ajax- provide a loose / lightweight way to interact with services; winjs might help.
  6. does your application have lot of algorithmic, complex logic implementation? javascript is a dynamic language and not strongly typed. The benefits of compiler catching your common coding mistakes will not be there. For example – even if you invoke a method without passing required number of arguments, code will not give error until executed. Now, think of complex product code base, making changes and handling regression. This is flip side of js that I have experienced. but decided to live with it. The power of language needs to be used with caution.
  7. for a specific project, you may want to pilot to verify that framework suffices your needs. There is certainly difference in controls available in xaml vs winjs.
  8. winjs won’t provide two way binding by default. I wrote a naïve two way binding impl. sufficient enough for our current needs.
  9. in sum total, I would say staying with html/css/js stack was the biggest motivator to stay with winjs.

Adding context menu for a WinJS custom control

Published August 12, 2013 1:18 pm

Recently, we were adding a WinJS custom control for image selection. It needs to handle things like – show progress ring during image load; show load error if image failed to load; allow user to select a new image; etc. The custom control also needs to display a context menu.

Windows.UI.Menu provides the way to show context menu as flyout and quite straight forward. Need to define the menu in the html, and show the flyout in an event handler on user gesture. Example html:

<div id="imageSelectControlMenu" data-win-control="WinJS.UI.Menu">
    <button data-win-control="WinJS.UI.MenuCommand" 
      data-win-options="{ extraClass: 'delete', label: 'Delete' }"></button>
    <button data-win-control="WinJS.UI.MenuCommand" 
      data-win-options="{ extraClass: 'undo-delete', label: 'Undo Delete' }"></button>
    <button data-win-control="WinJS.UI.MenuCommand" 
      data-win-options="{ extraClass: 'clear-new-selection', label: 'Clear New Selection' }"></button>
</div>

Example js:

 
_initializeEventHandlers: function initializeEventHandlers()
{
    this.element.addEventListener('contextmenu', this._oncontextmenu.bind(this));
},
_oncontextmenu: function oncontextmenu(event)
{
    var menu = document.querySelector('#imageSelectControlMenu');
    menu.winControl.show(this.element, 'right', 'center');
},

so far so good. This is where I hit the issue of context menu showing and hiding immediately. Context menu will show up and hide immediately in less than a sec. In process to get to the root cause of the issue, I tried GestureRecognizer which exposes high level gesture events when passed the mouse events for an element. There is a good sample available for it. It takes few minutes to digest what Gesture Recognizer provides. Few notes from my usage:

  1. Typically, it will come handy for a custom control where you want to control how to raise gesture events for mspointer events.
  2. I only used it to get ‘tapped’, ‘righttapped’ events. I did not use it for manipulation events or custom gesture events. DOM ‘click’ and ‘contextmenu’ events give the same functionality as ‘tapped’ and ‘righttapped’ events respectively.
  3. Sample code gives feel how to pass it mouse pointer events.

After using the GR, I found that the issue did not go away. After few minutes of debugging, root cause was found. It was missed ‘preventDefault()’ call in the handler for ‘contextmenu’ event.

 
_oncontextmenu: function oncontextmenu(event)
{
    var menu = document.querySelector('#imageSelectControlMenu');
    menu.winControl.show(this.element, 'right', 'center');
    event.preventDefault();
},

I need to this css to fix the layout of the context menu.

.my-custom-control .win-menu
{
    width: 10em;
    padding-left: 1em;
}

Reading a file into ArrayBuffer in WinJS application

Published August 8, 2013 11:02 am

Many a times when you are using an external javascript library into your winjs application, you come across apis that expect a parameter as ArrayBuffer. Windows storage apis like FileIO.readBufferAsync return IBuffer. In such case, How do one read the contents of a file into ArrayBuffer?

There are multiple solutions for this. One of the solution that I have come across is to read the DOM ‘File’ object using WinJS.xhr.

        var storage = Windows.Storage;
        storage.StorageFile.getFileFromApplicationUriAsync(new Windows.Foundation.Uri('ms-appx:///images/logo.png')).then(function ongetfile(file)
        {
            var blob = MSApp.createFileFromStorageFile(file);
            var url = URL.createObjectURL(blob, { oneTimeOnly: true });
            return WinJS.xhr({ url: url, responseType: 'arraybuffer' });
        }).then(function onreadbuffer(req)
        {
            var arrayBuffer = req.response;
        }).then(null, function onerror(error)
        {
            // TODO: handle error
        });