Early 2014, the Patterns & Practices teams at Microsoft released a new version of the Prism library, dedicated to the creation of business apps using C# and XAML on Windows 8.1 (a version for Windows 8 already existed since 2013, the team “just” updated the version to add the support of Windows 8.1).

In this article, we’ll provide the basics to use Prism to create a Windows Store application so let’s start !

Architecture

Here is the diagram of a typical Windows Store application that is developed using the Prism library:

 Logical architecture of a Windows Store business app that uses Prism

As you can see, this is a standard architecture: MVVM to separate the concerns of presentation, presentation logic, and model, a data access layer using repositories and some Services proxies to retrieve the data, etc. The good part is that some elements are directly provided by Prism (ViewBase, ViewModelBase, ViewModelLocator, Event Aggregator, etc.) so, you just have to provide the XAML code (View), the logic code (ViewModel) and the business objects (Model).

Creating the application

Creating the application is the same as creating any Windows Store application (File –> New Project) but, once Visual Studio has finished to create the project, you need to add reference to the following Nuget packages:

  • Prism.StoreApps: this is the class library that provides MVVM support with lifecycle management, and core services to a Windows Store app (see here for the list of all the features provided)
  • Prism.PubSubEvents: the Portable Class Library that contains classes that implement event aggregation (again, check here to see the class contains on the library)

image

Once this is done, derive the App class from the MvvmAppBase class, to allow your application to support the MVVM pattern and the core services (navigation, events aggregation, etc.):

sealed partial class App : MvvmAppBase

Don’t forget to change the base class of the file App.xaml too or you’ll get compile errors:

<storeApps:MvvmAppBase
    x:Class="DemoPrism.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:DemoPrism"
    xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps">

</storeApps:MvvmAppBase>

The MvvmAppBase class is an abstract class that define one method that need to be implemented: OnLaunchApplication. This method is used to perform the initial launch of the application so this is where we’ll define the page that’ll be launched on start:

protected override Task OnLaunchApplication(LaunchActivatedEventArgs args)
{
    NavigationService.Navigate("MainPage", null);

    return Task.FromResult<object>(null);
}

This method need to return a Task object so you can use Task.FromResult to return an empty task. To don’t have conflicts with the initial overridden methods, don’t forget to delete the OnLaunched and OnSuspending methods.

The code use the NavigationService property, which is Navigation Service that we can use to perform navigation within the application. Unfortunately, if you try to run this code, you’ll get the following exception:

SNAGHTML2de0d500

Indeed, by default, Prism use a particular convention for the Views: they need to be placed on the “Views” folder. In my case, I used to have the following structure on my applications:

image

So I have a “Views” folder but this folder contains sub-folders containing the big features of the application. So I need to find a way to tell the Prism library to look for the views on that sub-folders. And this can be done by overriding the GetPageType method of the MvvmAppBase class:

protected override Type GetPageType(string pageToken)
{
    var subPageToken = pageToken.Substring(0, pageToken.Length - pageToken.IndexOf("Page", StringComparison.Ordinal));

    var assemblyQualifiedAppType = this.GetType().GetTypeInfo().AssemblyQualifiedName;
    var pageNameWithParameter = assemblyQualifiedAppType.Replace(this.GetType().FullName, this.GetType().Namespace + ".Views.{0}.{1}");
    var viewFullName = string.Format(CultureInfo.InvariantCulture, pageNameWithParameter, subPageToken, pageToken);
    var viewType = Type.GetType(viewFullName);

    return viewType;
}

Now, if I execute the code, the application loads correctly and the page is displayed:

image

Registering services using Dependency Injection

This is not a mandatory steps but Prism has been a long time co-worker of Dependency Injection tools like Unity. So let’s start by adding the Nuget package of your choice (here, I’ll use Unity):

image

Then, declare a Unity container to register and resolve types and instances:

private readonly IUnityContainer _container = new UnityContainer();

You can then override the OnInitialize method of MvvmAppBase to register types and perform any other initialization:

protected override void OnInitialize(IActivatedEventArgs args)
{
    _container.RegisterInstance<INavigationService>(NavigationService);
    _container.RegisterType<IEventAggregator, EventAggregator>(new ContainerControlledLifetimeManager());
}

And, to be able to resolve the types, you just need to override the Resolve method:

protected override object Resolve(Type type)
{
    return _container.Resolve(type);
}

Now, let’s see how we can add the Views and the ViewModels to the application.

Creating a View and its ViewModel

The Views has nothing particular related to the Prism library. You just composed it like you used to do it so this is just XAML content that you defined using Visual Studio or Blend.

To define the ViewModel associated to the view, you can use the ViewModelLocator.AutoWireViewModel property:

xmlns:storeApps="using:Microsoft.Practices.Prism.StoreApps"
storeApps:ViewModelLocator.AutoWireViewModel="true"

Once this property is set to True, the ViewModelLocator will try to instanciate the corresponding ViewModel based on a particular convention: the ViewModels need to be located in the same assembly, in a namespace ended by .ViewModels and the ViewModel name must match the View name and ends with ViewModel. But this is always what you have in your application. Indeed, you can have your ViewModels in a separate assembly or you can have them within the folder containing the views, like I use to have:

image

Fortunately, you can once again change the way Prism is loading your ViewModels, by specifying the ViewModelLocator.SetDefaultViewTypetoViewModelTypeResolver method:

protected override void OnInitialize(IActivatedEventArgs args)
{
    _container.RegisterInstance<INavigationService>(NavigationService);
    _container.RegisterType<IEventAggregator, EventAggregator>(new ContainerControlledLifetimeManager());

    ViewModelLocator.SetDefaultViewTypeToViewModelTypeResolver((viewType) =>
    {
        var subPageToken = viewType.Name.Substring(0, viewType.Name.Length - viewType.Name.IndexOf("Page", StringComparison.Ordinal));

        var assemblyQualifiedAppType = this.GetType().GetTypeInfo().AssemblyQualifiedName;
        var pageNameWithParameter = assemblyQualifiedAppType.Replace(this.GetType().FullName, this.GetType().Namespace + ".Views.{0}.{1}ViewModel");

        var viewFullName = string.Format(CultureInfo.InvariantCulture, pageNameWithParameter, subPageToken, viewType.Name);
        var viewModelType = Type.GetType(viewFullName);

        return viewModelType;
    });
}

Now, if you execute your application and put a breakpoint to the ViewModel’s constructor, you’ll see that the execution is stopped correctly (the ViewModel has been correctly instantiated):

image

Also, thanks to the Dependency Injection we put in place with Unity, we can construct the ViewModel and get, in constructor’s parameters, the type we want to retrieve:

public class MainPageViewModel : ViewModel
{
    private readonly INavigationService _navigationService;
    private readonly IEventAggregator _eventAggregator;

    public MainPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator)
    {
        this._navigationService = navigationService;
        this._eventAggregator = eventAggregator;
    }
}

image

Handling navigation between pages

To handle navigation between pages, Prism library offers to developer the interface INavigationAware (already implemented by the base ViewModel class). This interface exposes 2 methods:

  • OnNavigatedFrom: which is called before the navigation occurred. You can use this method to preserve the state of your data during the navigation
  • OnNavigatedTo: which is called after the navigation to a page is performed. This method can be used to retrieve parameter sent from a page to another page.

So this interface is really helpful if you want to execute navigation to another page within a component which has nothing to do with navigation (like a ViewModel for example!). And to change to another page, we’ll use the methods provided by the INavigationService (that is injected to the ViewModel’s constructor thanks to the dependency injection):

image

Saving properties’ values between the application’s states

As you know, a Windows Store application have different state: Not Running, Running, Suspended and Terminated. This is your job to preserve the properties’ value between the different states of your application so when users are going back to the application, they don’t feel there was a kind of pause (or termination) during the application’s execution.

So let’s take a look at the following example:

private string _mySuperString;

public string MySuperString
{
    get
    {
        return this._mySuperString;
    }
    set
    {
        this.SetProperty(ref this._mySuperString, value);
    }
}

And the dedicated XAML interface:

<StackPanel Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
            VerticalAlignment="Center">
    <TextBox HorizontalAlignment="Center"
             VerticalAlignment="Center"
             Text="{Binding MySuperString, Mode=TwoWay}" />
    <Button Content="Click Me!"
            HorizontalAlignment="Center"
            VerticalAlignment="Center" />
</StackPanel>

If I enter some text on the Textbox, the property will be updated in memory, thanks to the databinding feature. Each time the application is suspended and  terminated by the OS (which determined when to kill suspended apps to retrieve some resources), the text entered in the Textbox is deleted from the memory. To stop that, I can simply add the RestoreState attribute to the property:

private string _mySuperString;

[RestorableState]
public string MySuperString
{
    get
    {
        return this._mySuperString;
    }
    set
    {
        this.SetProperty(ref this._mySuperString, value);
    }
}

image

Now, I can execute the application and simulate a termination done by the OS, by using the Suspend and shutdown feature from the Debug Location toolbar:

image

If I execute the application again, without having to add other code, the MySuperString property will be automatically populated and the user interface will be modified:

image

Of course, you can also add more complex objects to the State to retrieve them later. For that, you’ll need to use the ISessionStateService (which exposes a Dictionary object) that manages the automatic load and save during application exit and startup!

First, to get the ISessionStateService object from your ViewModel, you need to get it injected to the constructor:

public MainPageViewModel(INavigationService navigationService, ISessionStateService sessionStateService)
{
    this._navigationService = navigationService;
    this._sessionStateService = sessionStateService;
}

Don’t forget to register the instance during the app’s initialization:

protected override void OnInitialize(IActivatedEventArgs args)
{
    _container.RegisterInstance<INavigationService>(NavigationService);
    _container.RegisterInstance<ISessionStateService>(SessionStateService);
}

Now, you just need to add your object to the session’s state:

public void SaveToSessionState()
    {
        var users = new List<User> { new User { Id = Guid.NewGuid(), Name = "Thomas LEBRUN" } };

        this._sessionStateService.SessionState.Add("DemoKey", users);
    }

public class User
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

And, finally, you can check (when the user navigated to the ViewModel) if the key exists in the dictionary:

public override void OnNavigatedTo(object navigationParameter, NavigationMode navigationMode, Dictionary<string, object> viewModelState)
{
    base.OnNavigatedTo(navigationParameter, navigationMode, viewModelState);

    if (_sessionStateService.SessionState.ContainsKey("DemoKey"))
    {
        var users = _sessionStateService.SessionState["DemoKey"] as List<User>;
        if (users != null)
        {
            //
        }
    }
}

Now, if you execute the code and simulate an termination of the app, you got a correct execution… or not :)

image

You’ll see that an exception is raised:

image

If you take a look at the details of the exception, you’ll see something familiar if you use to work with data serialization:

image

“Type ‘System.Collections.Generic.List`1[[DemoPrism.Views.Main.User, DemoPrism, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]’ with data contract name ‘ArrayOfUser:http://schemas.datacontract.org/2004/07/DemoPrism.Views.Main’ is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types – for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.”

Indeed, to save the session state, the system will serialize the items and here, we try to serialize a type (User) that is not known by the DataContractSerializer. So we need to teach it all about our custom type(s). This is done by overriding the method OnRegisterKnownTypesForSerialization of the MvvmAppBase class:

protected override void OnRegisterKnownTypesForSerialization()
{
    base.OnRegisterKnownTypesForSerialization();

    SessionStateService.RegisterKnownType(typeof(User));
    SessionStateService.RegisterKnownType(typeof(List<User>));
}

And now, the termination of the app works successfully and when the user navigated to the page, we can check/retrieve the results from the session state:

image

Simple but terribly useful isn’t it ?! Now, let’s see how we can communicate from a component to another one!

Communication between components using the Event Aggregator

Sometimes, you might need to communicate some data from a component to another one. This can be from ViewModelA to ViewModelB, ViewModelA to ViewC, ViewB to ViewA, etc. All this elements have one thing in common: they are not loosely coupled so there are no links between them. So how can we communicate from a component to another one when they are not linked ?

The answer is 2 words: Event Aggregator. This is a design pattern, also known as Publish/Subscribe, which is used to send a message (from the publisher) that is catched by all the subscribers (Martin Fowler talked about the pattern on his blog).

So how does it works ? Well, first, you need to get a reference to the Event Aggregator instance. This can be done through the dependency injection of the ViewModel’s constructor:

public MainPageViewModel(INavigationService navigationService, IEventAggregator eventAggregator, ISessionStateService sessionStateService)
{
    this._navigationService = navigationService;
    this._eventAggregator = eventAggregator;
    this._sessionStateService = sessionStateService;
}

Or thanks to Dependency Injection container you choose to use:

var eventAggregator = UnityServiceHelper.UnityContainer.Resolve<IEventAggregator>();

Then, we need to create the event object that will be sent from the publisher to the subscribers. This object is a simple class that inherits from the PubSubEvent<T> class:

public class SessionStateSavedEvent : PubSubEvent<object>
{
}

Now, we just have to publish an instance of this event. To do so, we’ll use the GetEvent method of the EventAggregator object and we’ll call the Publish method:

this._eventAggregator.GetEvent<SessionStateSavedEvent>().Publish(null);

This method takes in parameter the object you want to send to the subscribers (in our case, we don’t want to use any parameters so we send the null value). Finally, we need to add a handler that will be raised when the event will be catched by the subscriber:

protected override void OnNavigatedTo(NavigationEventArgs e)
{
    base.OnNavigatedTo(e);

    var eventAggregator = UnityServiceHelper.UnityContainer.Resolve<IEventAggregator>();
    eventAggregator.GetEvent<SessionStateSavedEvent>().Subscribe(OnSessionStateSavedEventSubscribe);
}

private void OnSessionStateSavedEventSubscribe(object obj)
{
    //
}

And voilà! Once the publisher send an instance of our event, all the subscribers will be notified and their handlers will be invoked:

image image

Of course, there are plenty other possibilities when using the Event Aggregator like specifying on which thread the handler will be executed or like filtering which handlers need to be executed:

image

image

 

Prism allows a lot of more (validation of user input, performance optimizations, etc.) but I hope this first overview gave you all you need to take a further look at this very cool library !

 

Happy coding!

 

PS: The source code of the article is available here.

The FlipView control is very useful to display a set of data and display them with a DataTemplate. But imagine that you need to load 1000000 of customers: you’ll need to load all of them and set the ItemsSource property so the data can be shown. But loaded 1000000 objects in memory is not a very good idea in terms of performance so, let’s take a look at how we could prevent that!

First, you need to add an event handler to the SelectionChanged method of the FlipView:

private async void OnFlipViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    await this._viewModel.LoadMoreItemsAsync(this.flipView.SelectedIndex);
}

As you can see, we just call a method of our ViewModel, passing in parameters the current index of the FlipView. So all the magic is in the LoadMoreItemsAsync method of our ViewModel:

private int _offset;

private ObservableCollection<PostViewModel> _posts;
public ObservableCollection<PostViewModel> Posts
{
    get { return this._posts; }
    set { this.SetProperty(ref this._posts, value); }
}

public async Task LoadMoreItemsAsync(int currentIndex)
{
    if (currentIndex > 0)
    {
        var globalIndex = currentIndex % 10;
        var itemIndex = currentIndex - globalIndex;

        if (itemIndex <= 5)
        {
            this._offset = this._offset - 1;

            var rangedPost = await this.GetPostsAsync(this._offset);
            var posts = rangedPost as IList<Post> ?? rangedPost.ToList();
            if (posts.Any())
            {
                for (int i = 0; i <= posts.Count - 1; i++)
                {
                    var post = posts.ElementAt(i);

                    this.Posts.Insert(i, this.CreatePostViewModel(post));
                }
            }
        }
        else if (currentIndex >= this.Posts.Count - 5)
        {
            this._offset = this._offset + 1;

            var rangedPost = await this.GetPostsAsync(this._offset);
            var posts = rangedPost as IList<Post> ?? rangedPost.ToList();
            if (posts.Any())
            {
                foreach (var post in posts)
                {
                    var postViewModel = this.CreatePostViewModel(post);
                    if (postViewModel != null)
                    {
                        this.Posts.Add(postViewModel);
                    }
                }
            }
        }
    }
}

So how this method works exactly ? Well, basically, we load our “pages” by set of 10 items so we just check if we need to add the items at the end of the property bound to the ItemsSource or if we need to insert the items (starting from the index 0). Also, don’t forget to use an ObservableCollection (instead of a simple List) for the property databound otherwise, your GUI won’t be refreshed.

Of course, to make this happened, you need to have a service/backend that accepts to send data/items according to a page index.

Maybe there are other solutions (I’ve haven’t checked yet if ISupportIncrementalLoading can be used, in Windows 8.1, with the FlipView control but as far as I know, it didn’t work on Windows 8) but this one is pretty simple isn’t it ? :)

 

Happy coding!

Ok, I admit the title is a bit long and you may wonder what I’m talking about so let me explain.

On the application I’m working, I use a Listbox to display items and I wanted to start an animation when an item is selected. Of course, I could have simply edit the ListBoxItem style and modify the “Selected” visual state (as explained here) but, in my case, I wanted to be notified when the animation was finished (to redirect the user on another page).

So here is the solution I’ve found. On the SelectionChanged event handler, retrieve the current ListBoxItem:

private async void OnCategoriesSelected(object sender, SelectionChangedEventArgs e)
{
    if (e.AddedItems != null && e.AddedItems.Count > 0 && e.AddedItems[0] != null)
    {
        // The Listbox is bound to a List<Category> so when I get the AddedItems, I know they are of type Category.
        var selectedCategory = e.AddedItems[0] as Category;
        if (selectedCategory != null)
        {
            var listBoxItem = this.CategoriesListBox.ItemContainerGenerator.ContainerFromItem(selectedCategory) as ListBoxItem;
            if (listBoxItem != null)
            {
            }
        }
    }
}

Now that I have the ListBoxItem object, I simply create a Storyboard and begin it:

listBoxItem.RenderTransform = new CompositeTransform();

var swipeAnimation = new DoubleAnimationUsingKeyFrames();
swipeAnimation.KeyFrames.Add(new EasingDoubleKeyFrame
{
    Value = App.RootFrame.ActualWidth,
    KeyTime = KeyTime.FromTimeSpan(new TimeSpan(0, 0, 0, 0, 250))
});

Storyboard.SetTarget(swipeAnimation, listBoxItem);
Storyboard.SetTargetProperty(swipeAnimation, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.TranslateX)"));

var sb = new Storyboard();
sb.Children.Add(swipeAnimation);

await sb.BeginAsync();

Of course, feel free to create your custom animation here. Also, the extension method BeginAsync is defined as below:

public static Task BeginAsync(this Storyboard storyboard)
{
    var tcs = new TaskCompletionSource<bool>();

    EventHandler completedEventHandler = null;
    completedEventHandler = (sender, o) =>
    {
        storyboard.Completed -= completedEventHandler;
        tcs.TrySetResult(true);
    };
    storyboard.Completed += completedEventHandler;
    storyboard.Begin();

    return tcs.Task;
}

Now, after the call to the BeginAsync method, I can redirect my user to another page:

await sb.BeginAsync();

this.NavigationService.GoToQuestionsPage(selectedCategory.Id);

Here is a small video of the result:

 

Happy coding!

On Silverlight/Windows Phone, the FluidMoveBehavior can be used to animate the items of a ListBox when user adds or removes an item. But the behavior has no effect when the items are loaded and bound to the Listbox.

Imagine the following C# code corresponding to our ViewModel:

private ObservableCollection<Category> _categories;

public ObservableCollection<Category> Categories
{
    get
    {
        return this._categories;
    }
    set
    {
        this.Set(() => this.Categories, ref this._categories, value);
    }
}

public override async Task OnNavigatedTo(NavigationEventArgs navigationEventArgs, NavigationContext navigationContext)
{
    this.IsBusy = true;

    if (App.Categories == null)
    {
        App.Categories = await ClientServices.ClientServicesLocator.CategoriesService.GetAllCategoriesAsync();
    }

    this.Categories = new ObservableCollection<Category>(App.Categories);

    this.IsBusy = false;
}

And the associated XAML code:

<ListBox x:Name="CategoriesListBox" ItemsSource="{Binding Categories}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Name}"
                       Style="{StaticResource PhoneTextTitle2Style}"
                       FontSize="40"
                       controls:TiltEffect.IsTiltEnabled="True"
                       x:Name="CategoryNameTextBlock" />
        </DataTemplate>
    </ListBox.ItemTemplate>
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

If you apply the FluidMoveBehavior to the StackPanel of the ListBox and go to the page, you’ll see that the items are all loaded on the same time, with no effect.

To change this, we can replace the ViewModel code with this one:

public Action RefreshCategories { get; set; }

public override async Task OnNavigatedTo(NavigationEventArgs navigationEventArgs, NavigationContext navigationContext)
{
    this.IsBusy = true;

    if (App.Categories == null)
    {
        App.Categories = await ClientServices.ClientServicesLocator.CategoriesService.GetAllCategoriesAsync();
    }

    this.RefreshCategories();
}

As you can see, we no longer use a property of the ViewModel to bind it to the view: we just have an Action property that is raised once the data are loaded. In the code-behind of the page, here is how we use the Action property:

public CategoriesPage()
{
    InitializeComponent();

    this._viewModel = this.DataContext as CategoriesPageViewModel;
    if (this._viewModel != null)
    {
        this._viewModel.RefreshCategories = async () =>
        {
            this.CategoriesListBox.Items.Clear();

            foreach (var category in App.Categories)
            {
                this.CategoriesListBox.Items.Add(category);

                await Task.Delay(100);
            }

            this._viewModel.IsBusy = false;
        };
    }
}

So once the action is raised, we first starts by clearing the items on the ListBox then, for each items we want to add, we add it to the Items property of the control. Then, we make a small pause using Task.Delay, to give some time to the UI to be refreshed!

To get a more clean result, it’s also possible to modify the DataTemplate:

<DataTemplate>
    <TextBlock Text="{Binding Name}"
               Style="{StaticResource PhoneTextTitle2Style}"
               FontSize="40"
               controls:TiltEffect.IsTiltEnabled="True"
               x:Name="CategoryNameTextBlock">
        <TextBlock.Resources>
            <EventTrigger x:Name="LoadEventTrigger"
                          RoutedEvent="Canvas.Loaded">
                <BeginStoryboard>
                    <Storyboard x:Name="FadeIn">
                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
                                                       Storyboard.TargetName="CategoryNameTextBlock">
                            <EasingDoubleKeyFrame KeyTime="0" Value="0.01"/>
                            <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="1"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </TextBlock.Resources>
    </TextBlock>
</DataTemplate>

When the item is loaded, an animation is raised to change its opacity from 0 to 1. The result of the code can be seen on the first page of the following video (the animation on the second page will be covered in another post):

 

Happy coding!

Recently, I started to work on a Windows Phone application with all the data available through a Website (thanks to HtmlAgilityPack for helping me to parse the webpages).

All the parsing was quite easy but when I wanted to implement the search feature, I wondered how I could do this without any API ? Then, I discovered that the website was using a search form to propose the feature to its users so that was the way !

Here is the HTML code corresponding to the search form on the website:

<form method="post" action="http://www.mysyperwebsite.com/results.html">
    <input type="text" name="keyword" size="25" value="Enter some text..." onfocus="if (this.value=='Enter some text...') {this.value=''}" class="champs">&nbsp;
    <input type="button" onclick="ValidateSearch(this.form)" value="Search" alt="Search">
</form>

As we can see, the form send its data to the URL http://www.mysuperwebsite.com/results.html using the POST method. And that’s all we need to know! Indeed, we’ll do the same thing in our application: we’ll send a POST request to the indicated URL.

For that, we’ll use the HttpClient API and its PostAsync method (you can use the portable version of the HttpClient if you want). The PostAsync method takes in parameters the URI where to post the data and the content to send/post:

image

 

As we mimic the behavior of the form which post content, we’ll use the FormUrlEncodedContent object. This one takes in parameters a list of KeyValuePair, corresponding to the parameters sent by the search form:

var searchParameters = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("keyword", searchText) };

Here is the complete code:

var searchUri = "http://www.mysuperwebsite.com/results.html";
var searchParameters = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>("keyword", searchText) };

using (var httpclient = new HttpClient())
{
    using (var content = new FormUrlEncodedContent(searchParameters))
    {
        using (var responseMessages = await httpclient.PostAsync(new Uri(searchUri, UriKind.Absolute), content))
        {
            return await responseMessages.Content.ReadAsStringAsync();
        }
    }
}

And voilà! Now, if you execute this code, it will be the same as if user use the search form.

 

Happy coding (and new year) ! :)

Today, we are going to see a small but useful tip for those who want to prevent a screen to turn off while there is no user activity.

This might be useful, for example, if there are some videos playing on your app: while the video are playing, the user does not interact with the app thus, depending to your power settings, the screensaver can start or the screen can even turn off!

To prevent this case, Microsoft offers the DisplayRequest API. The usage is really simple:

private DisplayRequest _displayRequest;

public void PreventDisplayToTurnOff()
{
    if(_displayRequest == null)
        _displayRequest = new DisplayRequest();

    _displayRequest.RequestActive();
}

public void AllowDisplayToTurnOff()
{
    if (_displayRequest == null)
        _displayRequest = new DisplayRequest();

    _displayRequest.RequestRelease();
}

Even if the usage is really simple, be careful of the following:

  • Use DisplayRequest API only when it’s necessary. Indeed, preventing the screen to start screensaver or to turn off impact battery life!
  • Don’t forget to release each request as soon as possible

Here is a simple helper that, I hope, will help you (this one might not be totally proper but, at least, it works on my case :)):

public class DisplayRequestHelper : IDisposable
{
    private bool _requestActivated;
    private DisplayRequest _displayRequest;

    public void PreventDisplayToTurnOff()
    {
        if (!_requestActivated)
        {
            if (_displayRequest == null)
                _displayRequest = new DisplayRequest();

            _requestActivated = true;
            _displayRequest.RequestActive();
        }
        else
        {
            throw new InvalidOperationException("An active request is already pending.");
        }
    }

    public void AllowDisplayToTurnOff()
    {
        if (_requestActivated)
        {
            if (_displayRequest == null)
                _displayRequest = new DisplayRequest();

            _requestActivated = false;
            _displayRequest.RequestRelease();
        }
        else
        {
            throw new InvalidOperationException("No active request found to be released.");
        }
    }

    public void Dispose()
    {
        try
        {
            if (_displayRequest != null)
            {
                _displayRequest.RequestRelease();
            }
        }
        finally
        {
            _requestActivated = false;
            _displayRequest = null;
        }
    }
}

To use it, just use the Dispose pattern:

using (var helper = new DisplayRequestHelper())
{
    helper.PreventDisplayToTurnOff();
}

This way, you’re sure that the active request are release as soon as possible!

 

Happy coding!

Most of the apps available are used by single users but imagine you want to develop an application that will allow users to switch user accounts. This lead us to, at least, 2 majors issues: how to store the credentials of the users ? How to allow them to easily switch the current user account ?

 

Storing user credentials:

Credential Locker, available through the PaswwordVault class, allows you to add, get or delete credentials for user in a secure way (all passwords are encrypted and cannot be accessed by other users). Other good point: the credentials are roamed with the Microsoft account users will be able to retrieved its credentials from another device without no cost!

To use the PasswordVault, it’s pretty simple:

private void AddCredentials(string userName, string password)
{
    var passwordVault = new Windows.Security.Credentials.PasswordVault();
    passwordVault.Add(new PasswordCredential(AppName, userName, password));
}

private bool CheckCredentials(string userName, string password)
{
    var retVal = false;

    var passwordVault = new Windows.Security.Credentials.PasswordVault();

    try
    {
        var passwordCredential = passwordVault.Retrieve(AppName, userName);
        if (passwordCredential != null)
        {
            retVal = passwordCredential.Password == password;
        }
    }
    catch (Exception)
    {
        // If the passwordvault does not contains the credentials
        retVal = false;
    }

    return retVal;
}

Once added, the credentials can be viewed from the Credential Manager and we can confirmed that roaming is activated:

image

Ok so now that the credentials are saved and we know how we can retrieved them, let’s see how to display a

 

Switch user account:

The AccountsSettingsPane is a new class in Windows 8.1 that let you add the Accounts command to the Settings Flyout. This command is available, for example, on the native mail application:

image  image

To get the entry added to the SettingsPane, simply add the command to the SettingsPage:

image

Then, the AccountsSettingsPane pane is used like the SettingsPane. First, get a reference to the pane of the current view then, add an event handler to the CommandRequested event:

image

Finally, all the magic appears at the end where you add a provider account for your app and, for each credentials that to the app, you add a web account command (specifying which actions user will be able to take when he will select an account):

image

image

During my investigations, I found that Mike Taulty has posted a similar blog post with Azure Mobile Services (available here) where he gives more details about how to handle the deconnection/reconnection (so I’ll not give you more details here, just look at his post).

 

PS: Source code is available here.

 

Happy coding!

Windows Store Applications allows developers to provide search suggestions to users, so they can find quickly what they are looking for.

For example, you can provide search suggestions using a Web Services or you can even use local files for that. Here is a “naïve” way to do it:

SearchPane.GetForCurrentView().SuggestionsRequested += async (sender, eventArgs) =>
{
    var deferral = eventArgs.Request.GetDeferral();

    int countNumberOfFilesAdded = 0;

    var picturesFiles = await KnownFolders.PicturesLibrary.GetFilesAsync();
    foreach (var file in picturesFiles)
    {
        if (file.DisplayName.StartsWith(eventArgs.QueryText))
        {
            eventArgs.Request.SearchSuggestionCollection.AppendQuerySuggestion(file.DisplayName);

            countNumberOfFilesAdded++;

            if (countNumberOfFilesAdded == 5)
                break;
        }
    }

    deferral.Complete();
};

The previous code woks fine and search for the files in the Pictures library to provide suggestions. But this code caan be easily replace using the LocalContentSuggestionSettings API:

var settings = new LocalContentSuggestionSettings();
settings.Enabled = true;
settings.Locations.Add(KnownFolders.PicturesLibrary);
settings.AqsFilter = "ext:jpg";

SearchPane.GetForCurrentView().SetLocalContentSuggestionSettings(settings);

Result is strictly the same: the content of the Pictures library is used to provide search suggestions:

  1. Sub-folders are include in the search
  2. You can easily customize the filter using an Advanced Query Syntax (AQS) filter
  3. You can search in all the locations you want (the Locations property is a list of StorageFolder)
  4. Code is more easier!

 

Happy coding!

Here is a quick (but quite useful) tip for anyone who want to use NFC tags on its application.

NFC tags can be used on Windows (Phone) to open Internet links but they can also be used to open a particular application on your system.

For that, you just need to use/create a LaunchApp message that will be written on the tag:

var proximityDevice = Windows.Networking.Proximity.ProximityDevice.getDefault();
if (proximityDevice) {
    proximityDevice.ondevicearrived = function(device) {
        var launchArgs = "user=Thomas LEBRUN";

        // Package.manifest -> View XML Source -> <Application Id="...">
        var appId = "App";

        var appName = Windows.ApplicationModel.Package.current.id.familyName + "!" + appId;

        var launchAppArgs = launchArgs + "\tWindows\t" + appName;

        var dataWriter = new Windows.Storage.Streams.DataWriter();
        dataWriter.unicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.utf16LE;
        dataWriter.writeString(launchAppArgs);

        var launchAppId = proximityDevice.publishBinaryMessage("LaunchApp:WriteTag", dataWriter.detachBuffer());
       proximityDevice.stopPublishingMessage(launchAppId);
   };
}

The content of the tag is a string, where all the items are separated by “\t”:

  1. Some arguments that you want to use when the app starts
  2. The plateform (in our case, we need to specify “Windows”)
  3. The application name, which contains:
    1. The application id (this one can be found in the manifest file, under the attribute Id of the tag Application)
    2. The current package family name

Using this parameters, we can publish a particular message: LaunchApp:WriteTag. This tag/message will be recognize by the platform which will then ask for the user to open the dedicated application.

So you can easily imagine use this technique to create an new kind of authentification in your application (at least to provide the username).

 

Happy coding!

Scrolling in Windows Store applications is mostly done in horizontal mode. This is something quite easy to do with the GridView which support scrolling with mouse wheel but this can be a quite more complicated to do in Webview.

Indeed, in the Webview control, the mouse wheel scroll is done in vertical mode so here is a quick fix to perform the same scroll in horizontal mode.

To do this, you can use a JQuery plugin like JQuery.MouseWheel: https://github.com/brandonaaron/jquery-mousewheel

In your Webview, load JQuery and this plugin:

var scriptJQuery = "<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.js'></script>";
var scriptJQueryMouseWheel = "<script type='text/javascript' src='ms-appx-web:///Views/web/jquery.mousewheel.js'></script>";

var content = "<!doctype html><html lang=\"fr\"><head><link rel=\"stylesheet\" href=\"ms-appx-web:///Views/web/web.css\" type=\"text/css\" media=\"screen\" />" scriptJQuery + scriptJQueryMouseWheel + "</head>" +
    "<div id=\"articleContent\"><font id=\"article\" face=\"Segoe UI\">" +
        SelectedNews.Description +
    "</div></font>" +
"</html>";

webView.NavigateToString(content);

Once this is done, we can just add a small JavaScript function to handle the “MouseWheel” event:

var mouseWheelScript = "<script type=\"text/javascript\">" +
                        "$(function() {" +
                            "$('html, body').mousewheel(function(event, delta) {" +
                                "this.scrollLeft -= (delta * 50);" +
                                "event.preventDefault();" +
                            "});" +
                        "});" +
                    "</script>";

So the complete code is the following one:

var scriptJQuery = "<script type='text/javascript' src='http://code.jquery.com/jquery-1.7.js'></script>";
var scriptJQueryMouseWheel = "<script type='text/javascript' src='ms-appx-web:///Views/web/jquery.mousewheel.js'></script>";

var mouseWheelScript = "<script type=\"text/javascript\">" +
                        "$(function() {" +
                            "$('html, body').mousewheel(function(event, delta) {" +
                                "this.scrollLeft -= (delta * 50);" +
                                "event.preventDefault();" +
                            "});" +
                        "});" +
                    "</script>";

var content = "<!doctype html><html lang=\"fr\"><head><link rel=\"stylesheet\" href=\"ms-appx-web:///Views/web/web.css\" type=\"text/css\" media=\"screen\" />" + scriptResize + scriptVideo + scriptJQuery + scriptJQueryMouseWheel + mouseWheelScript + "</head>" +
    "<div id=\"articleContent\"><font id=\"article\" face=\"Segoe UI\">" +
        SelectedNews.Description +
    "</div></font>" +
"</html>";

webView.NavigateToString(content);

Now, each time the Webview will get the focus, user will be able to perform a horizontal scrolling using the mousewheel.

Pretty simple when you know!

Please note that the plugin’s file is loaded from ms-appx-web to allow Webview to load it correctly.

 

Happy coding!