Dev Stories

Xamarin Forms, the MVVMLight Toolkit and I: navigation and modal pages

Xamarin Forms, the MVVMLight Toolkit and I: navigation and modal pages

After showing you the basic MVVMLight Setup I am using as well as how to combine Xamarin.Forms’ DependencyService with our own Dependecy Injection-mechanism, this article is all about Navigation and modal pages in Xamarin.Forms.

Some preliminary words

I always liked how the MVVMLight Toolkit provided the NavigationService for my Windows & Windows Phone applications. That said, I tried to keep the idea of its NavigationService and ported it over to my Xamarin.Forms structure. I also extended it to fit the needs of my XF apps, for example for pushing modal pages (we’ll see that later). So for the base idea, I have to say thanks to Laurent Bugnion for the Windows platform implementation in MVVMLight and for keeping it simple. The later fact allows one to easily extend and adapt the service.

Also, there are tons of really good and also working samples around the web to show navigation in Xamarin.Forms. However, most of them follow another strategy, so I came to the point where decided to write my own implementation. My way may work for most scenarios without making a difference between navigation and showing modal pages. It provides an easy implementation and usage while following the MVVM pattern as far as it can go with Xamarin.Forms.

Components

My implementation has some key components, which I will describe briefly in this post:

  • Interfaces for Navigation and view events
  • Implementation of these interfaces
  • using the implementations in views
  • using the implementations in ViewModels

Interfaces for the win!

If we want to follow the MVVM pattern, we need to keep our Views completely separated from our ViewModels. A common practice to achieve this goal is the usage of interfaces, and so do I. If you have read my previous blog post about Dependency Injection, you know already a bit about the things we have to do. First, we will create an interface for the navigation itself:

public interface IXfNavigationService
{
    void Initialize(NavigationPage navigation);
    void Configure(string pageKey, Type pageType);
    (bool isRegistered, bool isModal) StackContainsNavKey(string pageKey);
    Task GoHomeAsync();
    Task GoBackAsync();
    Task GoBackModalAsync();
    int ModalStackCount { get; }
    string CurrentModalPageKey { get; }
    Task ShowModalPageAsync(string pageKey, bool animated = true);
    Task ShowModalPageAsync(string pageKey, object parameter, bool animated = true);
    int NavigationStackCount { get; }
    string CurrentPageKey { get; }
    Task NavigateToAsync(string pageKey, bool animated = true);
    Task NavigateToAsync(string pageKey, object parameter, bool animated = true);
}

As you can see, it is a pretty big interface that covers nearly all possible navigation scenarios of a Xamarin.Forms app (at least those that I had to deal with already). We are going to hook into a Xamarin.Forms  NavigationPage and configure our page handling cache with the configure method. As all navigation methods in Xamarin Forms are async, all navigational tasks will be implemented async as well. Additionally, we will have some helpful properties that we can use in our application implementation.

In Windows applications, we have some additional events for pages like  Loaded or OnNavigatedTo(and so on). Xamarin.Forms pages have something similar: ViewAppearing and ViewDisappearing. These two events correspond to OnNavigatedTo and OnNavigatedFrom in a Windows application. Sometimes, we need to know when those events happen in our ViewModels or other places behind the scenes to get stuff done. That’s why I created an interface for this purpose:

public interface IViewEventBrokerService
{
    event EventHandler<ViewEventBrokerEventArgs> ViewAppearing;
    event EventHandler<ViewEventBrokerEventArgs> ViewDisAppearing;
    void RaiseViewAppearing(string pageKey, Type pageType, bool isModal);
    void RaiseViewDisAppearing(string pageKey, Type pageType, bool isModal);
}

I also created my own EventArgs to make it easier to pass all data around (as you can see above). Here is the class:

public class ViewEventBrokerEventArgs : EventArgs
{
    public ViewEventBrokerEventArgs(string pageKey, Type pageType, bool isModal)
    {
        PageKey = pageKey;
        PageType = pageType;
        IsModal = isModal;
    }
    public string PageKey { get; private set; }
    public Type PageType { get; private set; }
    public bool IsModal { get; private set; }
}

Now that we have our interfaces defined, we are going the next step and have a look into their implementations.

IXfNavigationService implementation

First it is important to understand what Xamarin.Forms does when we are using a NavigationPage. We are performing a hierarchical navigation here. A must read is this page from the Xamarin documentation.

So you’re back from reading the documentation? Great, then lets have a look what our XfNavigationServiceimplementation does. It builds on top of the Xamarin.Forms NavigationPage, which implements the INavigation interface. Other solutions I saw are pulling down this interface and implement it in their implementation. I prefer to keep it simple and just use the already implemented interface in the Xamarin.Forms NavigationPage, which is mandatory for my implementation. We are pulling it into our implementation with the Initialize(NavigationPage navigationPage) method:

public void Initialize(NavigationPage navigationPage)
{
    _navigationPage = navigationPage;
}

We could also use a constructor injection here. Most of the time it would work, but I had some problems to get the timing right under certain circumstances. That’s why I prefer to manually initialize it to overcome these timing problems  – and it does not really hurt in real life applications to have it a bit more under control.

Before we are going to see the actual implementation, I need to break out of this scope and explain a threading issue.

Locking the current executing thread

Often we are running a lot of code at the same time. This could bring up some issues with ourXfNavigationService. If multiple threads try to change or execute code from our interface implementation, the result may not the one we desired. To prevent this, we would normally use the lock statement to allow only one thread modifying our code. Problem with the lock statement is, that we cannot run asynchronous code within.

As asynchronous code execution removes some of the headache in programming, we need a solution for this. And there is one, utilizing the SemaphoreSlim class of the .NET framework. Basically, the SemaphoreSlim class provides a single application Semaphore implementation. Without going deeper into it, we are replacing the lock statement we would normally use with this. We just need to initialize the SemaphoreSlim class as a private static member:

//using this instead of lock statement
private static SemaphoreSlim _lock = new SemaphoreSlim(1, 1);

This will only allow one thread to access the objects we are passing after it, and before releasing it (which is our responsibility). The code itself is recommended to run in a try..finally  block (you’ll see that below). Pretty much the same thing the lock statement would do, but with the possibility to run asynchronous code.

Back to the implementation

The next step is to allow registering pages with a name and their type from the ViewModelLocator. I am doing the same as in the standard MVVMLight implementation here:

//declare private member for the registered pages cache
private readonly Dictionary<string, Type> _pagesByKey = new Dictionary<string, Type>();


public void Configure(string pageKey, Type pageType) 
{ 
    //synchronous lock 
    _lock.Wait(); 
    try 
    { 
        if (_pagesByKey.ContainsKey(pageKey)) 
        { 
            _pagesByKey[pageKey] = pageType; 
        } 
        else 
        { 
            _pagesByKey.Add(pageKey, pageType); 
        } 
    } 
    finally 
    { 
        _lock.Release(); 
    } 
} 

Once we have our pages configured (we’ll see that later in this post), we are easily able to identify our registered pages for navigation purposes. Sometimes we want to get the current Page, so we need to implement a property for that, as well as for the current page key and the current modal page key:

public Page GetCurrentPage()
{
    return _navigationPage?.CurrentPage;
}


public string CurrentPageKey 
{ 
    get 
    { 
        _lock.Wait(); 
        try 
        { 
            if (_navigationPage?.CurrentPage == null) 
            { 
                return null; 
            } 
  
            var pageType = _navigationPage.CurrentPage.GetType(); 
  
            return _pagesByKey.ContainsValue(pageType) 
                ? _pagesByKey.First(p => p.Value == pageType).Key 
                : null; 
        } 
        finally 
        { 
            _lock.Release(); 
        } 
    } 
} 


public string CurrentModalPageKey 
{ 
    get 
    { 
        _lock.Wait(); 
  
        try 
        { 
            if (ModalStackCount == 1) 
            { 
                return null; 
            } 
  
            //only INavigation holds the ModalStack 
            var pageType = _navigationPage.Navigation.ModalStack.Last().GetType(); 
  
            return _pagesByKey.ContainsValue(pageType) ? _pagesByKey.FirstOrDefault(p => p.Value == pageType).Key 
                : null; 
        } 
        finally 
        { 
            _lock.Release(); 
        } 
    } 
} 

I found myself in situations where I needed to check if I am on a modal page, so lets add a method for that:

public (bool isRegistered, bool isModal) StackContainsNavKey(string pageKey) 
{ 
  
    bool isUsedModal = false; 
    bool isRegistered = false; 
  
    _lock.Wait(); 
    try 
    { 
        isRegistered = _pagesByKey.ContainsKey(pageKey); 
  
  
        if (isRegistered) 
        { 
            var pageType = _pagesByKey.SingleOrDefault(p => p.Key == pageKey).Value; 
  
            var foundInNavStack = _navigationPage.Navigation.NavigationStack.Any(p => p.GetType() == pageType); 
            var foundInModalStack = _navigationPage.Navigation.ModalStack.Any(p => p.GetType() == pageType); 
  
            if (foundInNavStack && !foundInModalStack || !foundInNavStack && !foundInModalStack) 
            { 
                isUsedModal = false; 
            } 
            else if (foundInModalStack && !foundInNavStack) 
            { 
                isUsedModal = true; 
            } 
            else 
            { 
                throw new NotSupportedException("Pages should be used exclusively Modal or for Navigation"); 
            } 
        } 
        else 
        { 
            throw new ArgumentException($"No page with key: {pageKey}. Did you forget to call the Configure method?", nameof(pageKey)); 
        } 
    } 
    finally 
    { 
        _lock.Release(); 
    } 
  
    return (isRegistered, isUsedModal); 
} 

This method checks if a page is registered correctly with its key and if it is presented modal at the moment. It also makes sure that an exception is thrown if a page is used modal AND in a navigation flow, which I think is a good practice to avoid problems when using the service. Finally, let’s add a Task for navigation to another page:

public async Task NavigateToAsync(string pageKey, object parameter, bool animated = true)
{
    //as we are async anyways, we can use the async implementation of SemaphoreSlim as well
    await _lock.WaitAsync();

    try
    {

        if (_pagesByKey.ContainsKey(pageKey))
        {
            var type = _pagesByKey[pageKey];
            ConstructorInfo constructor = null;
            object[] parameters = null;

            if (parameter == null)
            {
                constructor = type.GetTypeInfo().DeclaredConstructors.FirstOrDefault(c => !c.GetParameters().Any());

                parameters = new object[]
                {
                };
            }
            else
            {
                constructor = type.GetTypeInfo().DeclaredConstructors.FirstOrDefault(
                        c =>
                        {
                            return c.GetParameters().Count() == 1
                                   && c.GetParameters()[0].ParameterType == parameter.GetType();
                        });

                parameters = new[] { parameter };
            }

            if (constructor == null)
            {
                throw new InvalidOperationException("No constructor found for page " + pageKey);
            }

            var page = constructor.Invoke(parameters) as Page;
            if (_navigationPage != null)
            {
                await _navigationPage.Navigation.PushAsync(page, animated);
            }
            else
            {
                throw new NullReferenceException("there is no navigation page present, please check your page architecture and make sure you have called the Initialize Method before.");
            }
        }
        else
        {
            throw new ArgumentException(
                $"No page with key: {pageKey}. Did you forget to call the Configure method?",
                nameof(pageKey));
        }
    }
    finally
    {
        _lock.Release();
    }
}

I try to avoid passing parameters to pages while navigating, that’s why I added another task without the parameter overload as well:

public async Task NavigateToAsync(string pageKey, bool animated = true)
{
    await NavigateToAsync(pageKey, null, animated);
}

Of course we will run into situations where we want to go back manually, for example in a cancel function. So we have a method for that as well:

public async Task GoBackAsync()
{
    await _navigationPage.Navigation.PopAsync(true);
}

That’s  a lot of functionality already, but until now, we are only able to navigate to other pages and back. We want to support modal pages as well, so we’ll have some more methods to implement. They are following the same syntax as their navigation counterpart, so no surprise here:

public async Task ShowModalPageAsync(string pageKey, bool animated = true)
{
    await ShowModalPageAsync(pageKey, null, animated);
}

public async Task ShowModalPageAsync(string pageKey, object parameter, bool animated = true)
{
    await _lock.WaitAsync();

    try
    {

        if (_pagesByKey.ContainsKey(pageKey))
        {
            var type = _pagesByKey[pageKey];
            ConstructorInfo constructor = null;
            object[] parameters = null;

            if (parameter == null)
            {
                constructor = type.GetTypeInfo()
                    .DeclaredConstructors
                    .FirstOrDefault(c => !c.GetParameters().Any());

                parameters = new object[]
                {
                };
            }
            else
            {
                constructor = type.GetTypeInfo()
                    .DeclaredConstructors
                    .FirstOrDefault(
                        c =>
                        {
                            return c.GetParameters().Count() == 1
                                   && c.GetParameters()[0].ParameterType == parameter.GetType();
                        });

                parameters = new[] { parameter };
            }


            var page = constructor.Invoke(parameters) as Page;

            if (_navigationPage != null)
            {
                await _navigationPage.Navigation.PushModalAsync(page, animated);
            }
            else
            {
                throw new NullReferenceException("there is no navigation page present, please check your page architecture and make sure you have called the Initialize Method before.");
            }
        }
        else
        {
            throw new ArgumentException($"No page found with key: {pageKey}. Did you forget to call the Configure method?", nameof(pageKey));
        }
    }
    finally
    {
        _lock.Release();
    }
}

public async Task GoBackModalAsync()
{
    await _navigationPage.Navigation.PopModalAsync(true);
}

The last things that I wanted to note are properties that return the current counts of both the modal and the navigation stack of the navigation page as well as the GoHomeAsync() method to return to the root page. You will see these in the source code on Github.

IViewEventBrokerService implementation

Like I wrote already before, sometimes we need to know when a view is appearing/disappearing. In that case, the IViewEventBrokerService comes in. The implementation is pretty straight forward:

public class ViewEventBrokerService : IViewEventBrokerService
{
    public event EventHandler<ViewEventBrokerEventArgs> ViewAppearing;
    public event EventHandler<ViewEventBrokerEventArgs> ViewDisAppearing;


    public void RaiseViewAppearing(string pageKey, Type pageType, bool isModal)
    {
        ViewAppearing?.Invoke(this, new ViewEventBrokerEventArgs(pageKey, pageType, isModal));
    }

    public void RaiseViewDisAppearing(string pageKey, Type pageType, bool isModal)
    {
        ViewDisAppearing?.Invoke(this, new ViewEventBrokerEventArgs(pageKey, pageType, isModal));
    }
}

We have two events that can be raised with their corresponding Raise… methods. That’s all we have to do in here.

Implementing the Interfaces in Views (Pages)

Well, we have written a lot of code until here, now it is time to actually use it. As I want all my pages to be raise their appearing and disappearing automatically, I created a new base class, derived from Xamarin.Forms’ ContentPage:

public class XfNavContentPage : ContentPage
{
    private IViewEventBrokerService _viewEventBroker;
    private IXfNavigationService _navService;

    public XfNavContentPage()
    {
        _viewEventBroker = SimpleIoc.Default.GetInstance<IViewEventBrokerService>();
        _navService = SimpleIoc.Default.GetInstance<IXfNavigationService>();
    }

    public static BindableProperty RegisteredPageKeyProperty = BindableProperty.Create("RegisteredPageKey", typeof(string), typeof(XfNavContentPage), default(string), BindingMode.Default, propertyChanged: OnRegisteredPageKeyChanged);

    private static void OnRegisteredPageKeyChanged(BindableObject bindable, object oldValue, object newValue)
    {
        //todo, but not needed atm.
    }

    public string RegisteredPageKey
    {
        get { return (string)GetValue(RegisteredPageKeyProperty); }
        set { SetValue(RegisteredPageKeyProperty, value); }
    }

    private(bool isRegistered, bool isModal) _stackState { get; private set; }

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

        if (!string.IsNullOrEmpty(RegisteredPageKey))
        {
            _stackState = _navService.StackContainsNavKey(RegisteredPageKey);

            if (_stackState.isRegistered)
            {
                _viewEventBroker?.RaiseViewAppearing(RegisteredPageKey, GetType(), _stackState.isModal);
            }
        }
    }

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

        if (!string.IsNullOrEmpty(RegisteredPageKey))
        {
            if (_stackState.isRegistered)
            {
                _viewEventBroker?.RaiseViewDisAppearing(RegisteredPageKey, GetType(), _stackState.isModal);
            }
        }
    }
}

Let me explain what this base class does. It provides a BindableProperty(which is the Xamarin.Forms version of a DependencyProperty) that takes the registered key to provide it as a parameter. You can bind the key from your ViewModel or set it in code behind/XAML directly, all these ways will work. The base page implements our interfaces of the IXfNavigationService and the IViewBrokerServiceinterfaces as members and loads them in its constructor. The _stackStatemember is just an easy way to provide the needed data to the event-raising methods of our IViewEventBrokerservice. If used correctly, every page that derives from this base class will throw the corresponding events, which can be used in other parts of our application then.

Implementing the Interfaces in ViewModels

Like I did for Views, I am also creating a new base class for ViewModels that implement our two interfaces. Here is how it looks like:

public class XfNavViewModelBase : ViewModelBase
{
    protected readonly IXfNavigationService _navService;

    protected readonly IViewEventBrokerService _viewEventBroker;


    public XfNavViewModelBase()
    {
        _navService = SimpleIoc.Default.GetInstance<IXfNavigationService>();
        _viewEventBroker = SimpleIoc.Default.GetInstance<IViewEventBrokerService>();
        _viewEventBroker.ViewAppearing += OnCorrespondingViewAppearing;
        _viewEventBroker.ViewDisAppearing += OnCorrespondingViewDisappearing;
    }


    protected virtual void OnCorrespondingViewAppearing(object sender, ViewEventBrokerEventArgs e)
    {
    }

    protected virtual void OnCorrespondingViewDisappearing(object sender, ViewEventBrokerEventArgs e)
    {
    }

    private string _correspondingViewKey;

    public string CorrespondingViewKey
    {
        get => _correspondingViewKey; set => Set(ref _correspondingViewKey, value);
    }

    public bool IsBoundToModalView()
    {
        if (!string.IsNullOrEmpty(CorrespondingViewKey))
        {
            var checkIfIsModal = _navService.StackContainsNavKey(CorrespondingViewKey);

            if (checkIfIsModal.isRegistered)
            {
                return checkIfIsModal.isModal;
            }
        }
        return false;
    }
}

The XfNavViewModelBase implements both the IXfNavigationService and the IViewEventBrokerService interfaces. It also registers for the events thrown by IViewEventBrokerService. Making them virtual allows us to override them in derived ViewModels, if we need to. It has a string property to set the name of the View we want to use it in as well as a method that checks automatically if we are on a modal page if it gets called.

Using the created navigation setup

Now our navigation setup is ready it is time to have a look into how to use it. First we are going to create two pages, one for being shown modal, and one for being navigated to.

created-pages-snip

Then we’ll need to register and configure our services and pages in the ViewModelLocator. Remember the static RegisterServices() method we created in the first post? This is were we will throw the interface registrations in:

private static void RegisterServices() 
{ 
    //this one gets the correct service implementation from platform implementation 
    var osService = DependencyService.Get<IOsVersionService>(); 
  
    // which can be used to register the service class with MVVMLight's Ioc 
    SimpleIoc.Default.Register<IOsVersionService>(() => osService); 
  
    SimpleIoc.Default.Register<IXfNavigationService>(GetPageInstances); 
    SimpleIoc.Default.Register<IViewEventBrokerService, ViewEventBrokerService>(); 
}

The method contains already our IOsVersionService from my last blog post. We are also using DI here for the IXfNavigationService, as we need to Configure our page keys as well. First, we are adding static strings as page keys to the ViewModelLocator:

public static string ModalPageKey => nameof(ModalPage);
public static string NavigatedPageKey => nameof(NavigatedPage);

I am always using the nameof()-operator for this, because it makes life a bit easier. The second step is the missing piece in the service registration, the GetPageInstances() method that returns an instance of the IXfNavigationService interface implentation and registers our two pages via the Configure() method.

public static XfNavigationService GetPageInstances()
{
    var nav = new XfNavigationService();

    nav.Configure(ModalPageKey, typeof(ModalPage));
    nav.Configure(NavigatedPageKey, typeof(NavigatedPage));

    return nav;
}

This all will never work if we are not using a NavigationPage. So we are going to load MainPage.xaml as a NavigationPagein App.xaml.cs and pass the navigation page to our IXfNavigationService:

public App()
{
    InitializeComponent();

    var rootNavigation = new NavigationPage(new View.MainPage());
    MainPage = rootNavigation;
    SimpleIoc.Default.GetInstance<IXfNavigationService>().Initialize(rootNavigation);
}

Modifying pages

Until now, the pages we created are standard ContentPages, so we need to make them derive from our earlier created base class. First we are adding the namespace of our base class to it:

xmlns:baseCtrl="clr-namespace:XfMvvmLight.BaseControls;assembly=XfMvvmLight"

After that, we are able to use the base class to change ContentPage to baseCtrl:XfNavContentPage. Now open the code behind file for the page and change it to derive from XfNavContentPage as well:

public partial class ModalPage : XfNavContentPage

The sample project has a modal page and a navigated page to demonstrate both ways.

Setting up ViewModels

Normally, we also have a ViewModel for every additional page. That´s why I created a ModalPageViewModel as well as a NavigatedPageViewModel for the sample. They derive from the XfNavViewModelBase, so wie can easyily hook up the view events (if needed):

public class ModalPageViewModel : XfNavViewModelBase
{ 
    public ModalPageViewModel()
    {
        CorrespondingViewKey = ViewModelLocator.ModalPageKey;
    }
 
    protected override void OnCorrespondingViewAppearing(object sender, ViewEventBrokerEventArgs e)
    {
        base.OnCorrespondingViewAppearing(sender, e);
    }
 
    protected override void OnCorrespondingViewDisappearing(object sender, ViewEventBrokerEventArgs e)
    {
        base.OnCorrespondingViewDisappearing(sender, e);
    }
 
 
    private RelayCommand _goBackCommand;
 
    public RelayCommand GoBackCommand => _goBackCommand ?? (_goBackCommand = new RelayCommand(async () =>
    {
        await _navService.GoBackModalAsync();
    })); 
}

Remember the page keys we added earlier to the ViewModelLocator? We are just setting it as CorrespondingViewKey in the constructor here, but you could choose to it the way you prefer as well and can easily be bound to the view now:

<baseCtrl:XfNavContentPage 
   xmlns="http://xamarin.com/schemas/2014/forms"
   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
   xmlns:baseCtrl="clr-namespace:XfMvvmLight.BaseControls;assembly=XfMvvmLight"
   x:Class="XfMvvmLight.View.ModalPage" 
   RegisteredPageKey="{Binding CorrespondingViewKey}">
<!--code omitted for readability-->
</baseCtrl:XfNavContentPage>

As the sample pages have a button with back function, we have also a GoBackCommand bound to it. Now that’s already all we need to, and if we set a breakpoint in the event handling overrides, it will be hit as soon as the view is about to appear. See the sample working here in action on Android:

navigation-service-xf-mvvmlight

No we have a fully working and MVVM compliant navigation solution in Xamarin.Forms using the MVVMLight Toolkit.  I know there are several other toolkits and helpers floating around, but I like it to have less dependencies.  Another advantage of going this route: I am mostly familiar with the setup as I am already used to it from my Windows and Windows Phone applications. Creating this setup for navigation does not take a whole lot of time (the initial setup took me around 3 hours including conception). One can also pack the interfaces and the implementations in a (portable) class library to have all this work only once.

If you have feedback for me, feel free to leave a comment below. Like always, I hope this article is helpful for some of you. The updated sample application can be found here on my Github account.

Happy coding, everyone!

 

Posted by msicc in Android, Dev Stories, iOS, UWP, Xamarin, 1 comment

Xamarin Forms, the MVVMLight Toolkit and I: Dependecy Injection

Xamarin Forms is not always able to call platform specific code without some additional work to do. Thanks to the MVVM pattern, we are already familiar with the solution for this problem: Dependency Injection (DI).

Recap

Let’s just do a small recap what Dependency Injection means. The DI pattern’s main goal is to decouple objects and their dependencies. To separate concerns, we are using this structure nearly every time:

  • interface which defines the provided functionality
  • service class which provides the functionality defined in the interface
  • container that allows client classes/objects to use the functionality defined in the interface

The interface, our helpful dictator

DI always involves an interface, which dictates the functionality of the implementation. In Xamarin Forms, the interface rests inside the PCL/common project:

public interface IOsVersionService
{
    string GetOsVersion { get; } 
}

This interface gets the current installed version of the operating system. The next step ist to create the platform implementation, which is commonly defined as a service class.

Platform Implementation (service class)

We need to implement the service class for each platform. The setup is pretty easy, just add a new class and implement the interface for each platform:

implement-interface-vs2017

Tip: I am using a separate folder for platform implementations and set it to be a namespace provider. This makes it easier to maintain and I keep the same structure in all platform projects.

Let’s have a look into the specific implementations:

Android

public string GetOsVersion
{
    get
    {
        var versionNb = Build.VERSION.Release;
        var codename = Build.VERSION.Codename;
 
        return $"Android {versionNb} ({codename})";
    }
}

iOS

public string GetOsVersion
{
    get
    {
        try
        {
            return $"iOS {UIDevice.CurrentDevice.SystemVersion} ({UIDevice.CurrentDevice.UserInterfaceIdiom})";
 
        }
        catch
        {
            return "This demo supports iOS only for the moment";
        }
    }
}

Windows

public string GetOsVersion
{
    get
    {
        var currentOS = AnalyticsInfo.VersionInfo.DeviceFamily;
 
        var v = ulong.Parse(AnalyticsInfo.VersionInfo.DeviceFamilyVersion);
        var v1 = (v & 0xFFFF000000000000L) >> 48;
        var v2 = (v & 0x0000FFFF00000000L) >> 32;
        var v3 = (v & 0x00000000FFFF0000L) >> 16;
        var v4 = v & 0x000000000000FFFFL;
        var versionNb = $"{v1}.{v2}.{v3}.{v4}";
 
        return $"{currentOS} {versionNb} ({AnalyticsInfo.DeviceForm})";
    }
}

Now that we are able to fetch the OS Version, we need to make the implemation visible outside of the platform assemblies. On Android and iOS, this one is pretty straigt forward by adding this Attribute on top of the class:

[assembly: Xamarin.Forms.Dependency(typeof(OsVersionService))]

Because Universal Windows projects compile differently, we need to go a different route on Windows. To make the implementation visible, we need to explicit declare the class as an assembly to remain included first (otherwise the .NET Toolchain is likely to strip it away):

protected override void OnLaunched(LaunchActivatedEventArgs e)
{
    //other code for initialization, removed for readabilty
 
    //modified for .NET Compile
    List<Assembly> assembliesToInclude = new List<Assembly>();
    assembliesToInclude.Add(typeof(OsVersionService).GetTypeInfo().Assembly);

    Xamarin.Forms.Forms.Init(e, assembliesToInclude); 
}

Now that we have our platform implementations in place, we can go ahead and use the interface to get the OS versions.

Xamarin Forms DependencyService

With the static DependencyService class, Xamarin Forms provides a static container that is able to resolve interfaces to their native platform implementations. Using it is, once again, pretty straight forward:

private string _osVersionViaDs;
public string OsVersionViaDs
{
    get { return _osVersionViaDs; }
    set { Set(ref _osVersionViaDs, value); }
}
 
private RelayCommand _getOSVersionViaDsCommand;
 
public RelayCommand GetOsVersionViaDsCommand => _getOSVersionViaDsCommand ?? (_getOSVersionViaDsCommand = new RelayCommand(() =>
{
    OsVersionViaDs = DependencyService.Get().GetOsVersion; 
}));

In my sample application, I am using a button that fetches the OS version via Xamarin Forms DependencyService and display it into a label in my view.

Special case UWP, once again

To make this acutally work in an UWP application, we need to register the Service manually. Xamarin recommends to do so in the OnLaunched event, after Xamarin Forms is initialized:

//in OnLaunched event (App.xaml.cs)
//manually register for DependencyService 
//AFTER Forms is initialized but BEFORE VMLocator is initialized:
Xamarin.Forms.DependencyService.Register<OsVersionService>();

Only with that extra line of code, it will actually work like it should. If you want to know more on the fact that UWP needs a separate solution, take a look here into the Xamarin docs.

Why use the MVVMLight Toolkit’s Ioc?

There are several reasons. First is of course, purely personal: because I am used to write code for it. But there are also technical reasons:

  • support for cunstroctor injection
  • interface implementations can have parametered constructors
  • MVVMLight supports additional features like named instances and immediate creation on registration
  • in MVVM(Light) applications, you are very likely using DI on Xamarin Forms level, anyway (like in a NavigationService)

You see, there are some (in my opinion) good reasons to use the built in Ioc of the MVVMLight Toolkit.

How to use SimpleIoc and DependencyService together

If you are not relying on the DI-System of Xamarin Forms, you will have to write a lot of code yourself to get the platform implementations. That is not necessary, though. As our ViewModelLocator normally is already part of the Xamarin Forms PCL project, it has access  to the DependencyService and can be used to get the right implementation:

//this one gets the correct service implementation from platform implementation
var osService = DependencyService.Get();
 
// which can be used to register the service class with MVVMLight's Ioc
SimpleIoc.Default.Register<IOsVersionService>(() => osService);

This works pretty well for most implementations and provides us the possibility to use all the features MVVMLight provides. The usage then matches to what we are already familiar with:

private string _osVersionViaSimpleIoc;
public string OsVersionViaSimpleIoc
{
    get { return _osVersionViaSimpleIoc; }
    set { Set(ref _osVersionViaSimpleIoc, value); }
} 
 
private RelayCommand _getOSVersionViaSimpleIocCommand;
 
public RelayCommand GetOsVersionViaSimpleIocCommand => _getOSVersionViaSimpleIocCommand ?? (_getOSVersionViaSimpleIocCommand = new RelayCommand(() =>
{
    OsVersionViaSimpleIoc = SimpleIoc.Default.GetInstance().GetOsVersion; 
}));

If you do not want (or it is not possible due to complexity) register the platform implementation directly in the ViewModelLocator, you  can go down another route. You could create a new interface in the Xamarin Forms PCL which references the interface with the platform implentation as a member. Your implementation of this new interface (in Xamarin Forms) will be responsible for the getting the instance of the platform implementation via the built in DepenencyService.

I already used both ways in my recent Xamarin projects, but I prefer the first way that I described above.

Conclusion

Due to the fact that we know the DI pattern already as we (of course) follow the MVVM pattern in our applications, there is no big mystery about using the built in DependencyService of Xamarin Forms. We can easily integrate it into the MVVMLight Toolkit and combine the best of both worlds this way.

Nonetheless, I know that also some beginners are following my posts, so I tried to describe everything a bit more extended. As always, I hope this post is helpful for some of you. In my next post, I will show you how I solved the Navigation “problem” in my Xamarin Forms applications. In the meantime, you can already have a look at the sample code on Github.

Happy coding, everyone!

Posted by msicc in Android, Dev Stories, iOS, UWP, Xamarin, 2 comments

Xamarin Forms, the MVVMLight Toolkit and I (new series)

Like some of you may have already registered, I have been doing the next step and went cross platform with my personal projects. I am primarily using Xamarin Forms, because I eventually like XAML a little too much. I took a break from round about 2 years on my Xamarin usage, and I am happy to see that it has improved a lot in the meantime. While Xamarin Forms still has room for improvementes, one can do already real and serious projects with it. As I like the lightweight MVVMLight toolkit as much as I like XAML, it was a no-brainer for me to start also my recent Xamarin projects with it.

There is quite some setup stuff to do if you want get everything working from the Xamarin Forms PCL, and this post will be the first in a series to explain the way I am currently using. Some of the things I do may be against good practice for Xamarin Forms, but sometimes one has to break out of them to write code more efficiently and also maintain it easier.

Installing MVVM Light into a Xamarin Forms PCL project

Of course, we will start with a new Xamarin Forms project. After selecting the type Cross Platform App in the New Project Dialog in Visual Studio, you’ll be presented with this screen, which was introduced in the Cycle 9 Release of Xamarin:

Select Xamarin Forms as UI Technology and PCL as Code Sharing Strategy to start the solution creation. As it creates several projects, this may take some time, so you may be able to refill your coffee cup in the meantime. Once the project is created, you’ll see 4 projects:

Before we are going to write some code, we will update and add the additional packages from within the NuGet Package Manager. If your are not targeting the Android versions 7.x , Xamarin Forms is not able to use the latest Android Support libraries, so you’ll have to stick with version 23.3.0 of them (see release notes of Xamarin Forms). Since it makes sense for a new app to target the newest Android version, we’ll be updating the Android Support packages for our sample app as well.

If the NuGet Package manager demands you to restart, you’ll better follow its advise. To verify everything is ok with the updated NuGet packages, set the Android project as Startup project and let Visual Studio compile it.

If all goes well, let’s make sure we are using the right UWP compiler version for Visual Studio 2015. The .NETCORE package for the UWP needs to be of Version 5.2.x, as 5.3 is only compatible with Visual Studio 2017.

Once the packages are up to date, we’ll finally download and install MVVMLight. As we will host all of our ViewModel Logic in Xamarin Forms, together with their Views, we just need to install it into the Portable library and into the UWP project:

There will be no changes to the project except adding the reference. We need to set up the structure ourselves. First, create two new folders, View and ViewModel:

Move the MainPage into the View Folder and adjust the Namespace accordingly. The next step is to setup a ViewModelLocator class, which takes a central part of our MVVM structure. Here is what you need for the base structure:

    public class ViewModelLocator
    {
        private static ViewModelLocator _instance;
        public static ViewModelLocator Instance => _instance ?? (_instance = new ViewModelLocator());

        public void Initialize()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            RegisterServices();        

        }

        private static void RegisterServices()
        {
            //topic of another blog post
        }

        #region ViewModels  
        #endregion

        #region PageKeys
        #endregion
    }

You may notice some things. First, I am using the singleton pattern for the ViewModelLocator to make sure I have just one instance. I had some problems with multiple instances on Android, and using a singleton class helped to fix them. The second part of the fix is to move everything that is normally in the constructor into the Initialize() method. Now let’s go ahead, add a MainViewModel to the project and to the ViewModelLocator:

 

        public void Initialize()
        {
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
            RegisterServices();
            SimpleIoc.Default.Register<MainViewModel>();
        }

        #region ViewModels
        public MainViewModel MainVm => ServiceLocator.Current.GetInstance<MainViewModel>();
        #endregion

Let’s give the MainViewModel just one property which is not subject to change (at least for now):

public string HelloWorldString { get; private set; } = "Hello from Xamarin Forms with MVVM Light";

The next step is to get the App.xaml file code right, it should look like this:

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
             x:Class="XfMvvmLight.App" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             d1p1:Ignorable="d" 
             xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:forms="http://xamarin.com/schemas/2014/forms" 
             xmlns:vm="clr-namespace:XfMvvmLight.ViewModel" >
  <Application.Resources>
    <!-- Application resource dictionary -->
    <forms:ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
      <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
    </forms:ResourceDictionary>
  </Application.Resources>
</Application>

Now that we have set up the baisc MVVM structure, we are going to connect our MainViewModel to our MainPage. There are two ways to do so.

In Xaml:

<ContentPage.BindingContext>
    <Binding Path="MainVm" Source="{StaticResource Locator}" />
</ContentPage.BindingContext>

in Code:

        public MainPage()
        {
            InitializeComponent();

            this.BindingContext = ViewModelLocator.Instance.MainVm;
        }

After that, just use the HelloWorldString property of the MainViewModel as Text in the already existing Label:

    <Label Text="{Binding HelloWorldString}"
           VerticalOptions="Center"
           HorizontalOptions="Center" />

Before we are able to test our code, we need to make sure our ViewModelLocator is initialized properly:

Android:

    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        protected override void OnCreate(Bundle bundle)
        {
            //TabLayoutResource = Resource.Layout.Tabbar;
            //ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);

            ViewModelLocator.Instance.Initialize();

            LoadApplication(new App());
        }
    }

iOS:

    [Register("AppDelegate")]
    public partial class AppDelegate : global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate
    {
        //
        // This method is invoked when the application has loaded and is ready to run. In this 
        // method you should instantiate the window, load the UI into it and then make the window
        // visible.
        //
        // You have 17 seconds to return from this method, or iOS will terminate your application.
        //
        public override bool FinishedLaunching(UIApplication app, NSDictionary options)
        {
            global::Xamarin.Forms.Forms.Init();

            ViewModelLocator.Instance.Initialize();

            LoadApplication(new App());

            return base.FinishedLaunching(app, options);
        }
    }

UWP:

//in App.xaml.cs:
        protected override void OnLaunched(LaunchActivatedEventArgs e)
        {

#if DEBUG
            if (System.Diagnostics.Debugger.IsAttached)
            {
                this.DebugSettings.EnableFrameRateCounter = true;
            }
#endif

            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();

                rootFrame.NavigationFailed += OnNavigationFailed;

                Xamarin.Forms.Forms.Init(e);

                ViewModelLocator.Instance.Initialize();

                if (e.PreviousExecutionState == ApplicationExecutionState.Terminated)
                {
                    //TODO: Load state from previously suspended application
                }

                // 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
                rootFrame.Navigate(typeof(MainPage), e.Arguments);
            }
            // Ensure the current window is active
            Window.Current.Activate();
        }

Let’s test our app on all platforms by building and deploying them:

Android

 

iOS Screenshot – post will be updated 

 

UWP

If you get the same screens, you are all set up to use Xamarin Forms with MVVMLight.

Conclusion

I know there are several specialized MVVM frameworks/toolkits floating around, which are commonly used for Xamarin Forms. As I am quite used to the MVVMLight toolkit, I prefer it over them. It is a lightweight solution, and I have more control over the code that is running than with the other options. I know I have to handle a lot of things in this case on my own (Navigation for example), but these will get their own blog posts. Starting with one of the future posts in this series, I will provide a sample app on my Github account.

If you have feedback or questions, feel free to get in contact with me via comments or on my social accounts. Otherwise, I hope this post and the following ones are helpful for some of you.

Happy coding, everyone!

Posted by msicc in Android, Dev Stories, iOS, Xamarin, 2 comments

[Updated] How to create a pure icon button for your UWP app

[Updated: the first version of this blog post was using a UserControl. Thanks to a discussion on Twitter, I realized that wrapping it into a UserControl is overblown (yes, sometimes I tend to write more code than necessary). This is the updated version using only a Style for the button.]

When writing apps, you often come along a point where you want to style controls differently than the original style. Today, I‘ll show you a pure icon button that does not show the surrounding shape and borders. Instead, it highlights the icon of the button when hovering over it, while it changes the color to the user’s accent color when it gets pressed. Here is a little animation of what I am talking about:cromeless button demo

It all begins with the default style of the Button control, which you can see here. We are going to modify this Style until it matches the above animation. The first thing we change is the BackgroundBrush – set it to ‘Transparent’ to get rid of the grey shape that the button control comes with when hovering over it or pressing it:

<Setter Property="Background" Value="Transparent"/>

As we want an icon button, we need to choose a common source for the icons as well. I am using a Path Shape as the icon source, as it allows modifications to be done in XAML. So the next step is to add a Path shape to the Style:

                            <Path x:Name="PathIcon"
                                  Data="{TemplateBinding Content}"
                                  Stretch="Uniform"
                                  Fill="{TemplateBinding Foreground}"
                                  Stroke="Transparent"
                                  StrokeThickness="1"
                                  Margin="4"
                                  RenderTransformOrigin="0.5,0.5">
                                <Path.RenderTransform>
                                    <TransformGroup>
                                        <TransformGroup.Children>
                                            <RotateTransform Angle="0" />
                                            <ScaleTransform ScaleX="1" ScaleY="1" />
                                        </TransformGroup.Children>
                                    </TransformGroup>
                                </Path.RenderTransform>
                            </Path>

In this case, as we just want to use the icon within our button, we can safely remove the ‘ContentPresenter’ part in the Style. We have made quite some progress already, but that all does not make the control behaving like in the animation yet.

Now it is the time to modify the CommonStates of the Button’s style. Our Button uses only an icon, so we need to add the color states for the Path’s ‘Fill (=Foreground)’ to the states. Here are the modifications:

‘PointerOver’ state:

                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>

‘Pressed’ state:

                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundAccentBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>

‘Disabled’ state:

                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>

To get the icon’s outline highlighting, we are going to use the Path’s ‘Stroke (=Border)’ property. Add these modifications to the Style in XAML:

‘PointerOver’ state:

                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>

‘Pressed’ state:

                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                            </ObjectAnimationUsingKeyFrames>

‘Disabled’ state:

                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                            </ObjectAnimationUsingKeyFrames>

All that is left is to use the Style on any desired button:

    <Button x:Name="BaseButton" Style="{StaticResource TransparentButtonStyle}"></Button>

If you now use this one in an application, you will get the same result as in the initial animation.

For easier use, here is the complete code:

        <Style x:Key="TransparentPathIconButtonStyle" TargetType="Button">
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
            <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}"/>
            <Setter Property="BorderThickness" Value="{ThemeResource ButtonBorderThemeThickness}"/>
            <Setter Property="Padding" Value="8,4,8,4"/>
            <Setter Property="HorizontalAlignment" Value="Stretch"/>
            <Setter Property="VerticalAlignment" Value="Stretch"/>
            <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
            <Setter Property="FontWeight" Value="Normal"/>
            <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
            <Setter Property="UseSystemFocusVisuals" Value="True"/>

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Normal">
                                        <Storyboard>
                                            <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="PointerOver">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAccentBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <PointerUpThemeAnimation Storyboard.TargetName="RootGrid"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Pressed">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlForegroundAccentBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <PointerDownThemeAnimation Storyboard.TargetName="RootGrid"/>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}"/>
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Stroke" Storyboard.TargetName="PathIcon">
                                                <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>

                            <Path x:Name="PathIcon"
                                  Data="{TemplateBinding Content}"
                                  Stretch="Uniform"
                                  Fill="{TemplateBinding Foreground}"
                                  Stroke="Transparent"
                                  StrokeThickness="1"
                                  Margin="4"
                                  RenderTransformOrigin="0.5,0.5">
                                <Path.RenderTransform>
                                    <TransformGroup>
                                        <TransformGroup.Children>
                                            <RotateTransform Angle="0" />
                                            <ScaleTransform ScaleX="1" ScaleY="1" />
                                        </TransformGroup.Children>
                                    </TransformGroup>
                                </Path.RenderTransform>
                            </Path>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

As always, I hope this post is helpful for some of you. If you have questions/ideas for improvements or just want to talk about the control, feel free to leave a comment below.

Happy Coding, everyone!

Posted by msicc in Dev Stories, UWP, 3 comments

[Updated] How to create a multi architecture NuGet Package from a UWP class library

Like I already announced in my last blog post about UWP AppServices, I am going to show you how to create a NuGet package for UWP class libraries. I am going to go through the whole process, and provide you the steps I found as easiest (it may be the case that there are other ways for the single steps, too). I am continuing with my AppServices sample to show you all the steps I did.

Preparations

The first step is to download the latest NuGet.exe. This command line application will do all the work that is needed to create the package. Once downloaded, let’s do some modifications to our project.

It is good practice to put all the NuGet stuff into a folder in your project. That’s what we’re doing now, adding a folder named NuGet and put the NuGet.exe file in it (create the folder and copy and paste it in file explorer). The next step we would do now is to open the Package Manager Console in Visual Studio and call the nuget.exe with the parameter ‘spec’ to create a .nuspec file. The.xml formatted .nuspec file describes the structure of the NuGet package.

Because we need a multi architecture package for our Universal class library, I prefer another approach. I created a sample .nuspec file that already describes part of the structure that we need.  After pasting the file in, change the file name to match “[projectname].nuspec”. To add the file to your project in Visual Studio, click on the ‘ Show All Files’ button on top of the Solution Explorer Window. Now you will see the previously added NuGet folder and the .nuspec file. Right click on the renamed .nuspec file and select  ‘Include in Project’:

image

Inside the .nuspec file

Let’s have a look into the .nuspec file. The first part is the ‘metadata’ part, which describes the file’s properties:

    <metadata>
        <id>$title$</id>
        <version>$version$</version>
        <title>Simple Leet AppService Handler</title>
        <authors>$author$</authors>
        <owners>$owner$</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>$description$</description>
        <copyright>Copyright ©  2016</copyright>
      
        <dependencies>
        </dependencies>
    </metadata>

Just replace the the $-enclosed variables with your data. The more interesting part in this case is the dependencies part. With the Universal app platform, Microsoft introduced the .NETCore package that provides all the APIs. It is very hard to maintain the dependencies manually. Luckily, there is already a Nuget package that helps us to automate this process: NuSpec Dependency Generator.

Just add the package to your project and compile it. That’s it, you have all the dependencies in your .nuspec file:

    <dependencies>
      <group targetFramework="uap10.0">
        <dependency id="System.Diagnostics.Debug" version="4.0.10" />
        <dependency id="System.Runtime" version="4.0.20" />
        <dependency id="System.Runtime.WindowsRuntime" version="4.0.10" />
        <dependency id="System.Threading.Tasks" version="4.0.10" />
      </group>
    </dependencies>

Now that we have the dependencies in place, we’re ready for the next step: creating the package file structure. As we want a multi architecture package, we need to compile the project for every cpu architecture. This is done pretty simple, just select Release mode and build the project for all architectures:

Screenshot (97)

To check if we have all files in place, just open the corresponding architectures’ folder in the bin folder of your project:

Screenshot (98)

The next part is to add these folders to the .nuspec file within the ‘files’ tag:

  <files>
    <file src="..\bin\ARM\Release\SampleAppServiceConnector.dll" target="runtimes\win10-arm\lib\uap10.0" />
    <file src="..\bin\ARM\Release\SampleAppServiceConnector.pdb" target="runtimes\win10-arm\lib\uap10.0" />
    <file src="..\bin\x64\Release\SampleAppServiceConnector.dll" target="runtimes\win10-x64\lib\uap10.0" />
    <file src="..\bin\x64\Release\SampleAppServiceConnector.pdb" target="runtimes\win10-x64\lib\uap10.0" />
    <file src="..\bin\x86\Release\SampleAppServiceConnector.dll" target="runtimes\win10-x86\lib\uap10.0" />
    <file src="..\bin\x86\Release\SampleAppServiceConnector.pdb" target="runtimes\win10-x86\lib\uap10.0" />
  </files>

Noticed that we use the ‘runtimes’ folder with the corresponding architecture structure folders? This is how we need to set it up for multi architectural packages. Including the .pdb files is always a good practice, even with the missing symbolication in UWP applications (at least for now. I was told from inside Microsoft that they are working on this, but it seems to be a very complicated process for .NET native compiled applications).

Very important: the entry reference

This alone does not work, though. We need a reference that we can use as entry point for our package. To do this, we need to add an additional folder entry to our .nuspec file:

    <file src="..\bin\Release\SampleAppServiceConnector.dll" target="ref\uap10.0" />
    <file src="..\bin\Release\SampleAppServiceConnector.pri" target="ref\uap10.0" />

[Update:] Now that we have added this folder structure to the .nuspec file, the only thing we need to do is add an AnyCPU compiled .dll. Regarding some feedback I received on Twitter, it should work if you compile the library as AnyCPU like a lot of devs are used to. I you do not have success with that like me, you can also convert the x86 .dll into an AnyCPU .dll by removing the 32Bit-flag.  Here is how to do it:

  1. Copy the x86-.dll file  into the Release folder under the bin folder of your project
  2. Copy the x86-.dll and .pri file into the Release folder
  3. open the Visual Studio Developer Command Prompt (type ‘dev’ into the start menu, it will appear there)
  4. type:  corflags.exe /32bitreq- [path to Release folder]\[dll-Name].dll
  5. the result should look like this:Screenshot (101)

If you have additional files like xaml files, you would need to add a new folder in the uap10.0 folder (with the same name that your project has). I’ll update this post and the sample once I have a matching sample at hand.

Creating and testing the package!

Now we are finally able to pack the NuGet package. As we have the Developer Command Prompt already open, lets change the running directory to match the NuGet folder in our project. All we then need to do is to run the pack command of the nuget.exe that we already placed in there:

image

And that’s it. We have our NuGet Package in place. Now let’s test our package, before we are going to upload it to nuget.org. All you need to do is to have a folder for your NuGet packages on your machine. I made a folder called ‘TestNuget’ on mine, and copied the package into it (which is the same as the Nuget push command we’ll see later).

To add this folder as package source, open the ‘Options’ menu in Visual Studio and select ‘Package Sources’ in the NuGet Package Manager entry. Hit the add symbol on top and add your folder:

Screenshot (104)

Now if you open the Package Manager and select your local folder as source, you will be able to install and test your package:

image

Publishing the package to nuget.org (or your NuGet server)

The final step is to publish the newly generated package to nuget.org or your own NuGet server. As we still have the Developer CMD opened, we simply use the following command:

nuget push [path to your package.dll] [nuget.org API Key]

Another alternative would be to use the nuget.org website to upload the package: https://www.nuget.org/packages/upload (the page is self explanatory).

That’s it, your NuGet package is available for all you consider to use it. I also updated the sample of my last blog post on GitHub to include these changes, if you want to play around.

Some of you may go a different route for some steps. I have found this a good way that is also kind of memorable (for me). I would love to hear feedback on this and to discuss this, so feel free to leave me a comment.

Like always, I hope this post is helpful for some of you. Happy coding, everyone!

Posted by msicc in Dev Stories, UWP, wpdev, 3 comments

How to add and consume an AppService to your UWP app (complete walkthrough)

One of the very cool and helpful new features Microsoft added for UWP apps are AppServices. AppServices allow your application to provide functionality to other applications without even being launched. This post shows how to add and consume an AppService.

Creating the AppService

An AppService is a background task that is hosted by your application. To add an AppService to your existing application, right click on the solution name in the Solution Explorer and select ‘add new  project’. Under category Windows\Universal, select ‘Windows Runtime Component’, give it a name and click on ‘OK’:

image

This adds a new project to your solution. Rename or Replace Class1.cs to something that matches your need (in my sample, I just use ‘Handler’). The next step is to implement the IBackgroundTask interface:

image

This will add the ‘Run(IBackgroundTaskInstance taskInstance)’ method to the class. Before we continue with to integrate our AppService further into the system, we need to declare two members in the Handler class:

        private BackgroundTaskDeferral _backgroundTaskDeferral;
        private AppServiceConnection _appServiceConnection;

Now that we have those two in place, let’s have a look inside the Run method:

       public void Run(IBackgroundTaskInstance taskInstance)
        {
            //get the task instance deferral
            this._backgroundTaskDeferral = taskInstance.GetDeferral();

            //hooking up to the Canceled event to close app connection
            taskInstance.Canceled += OnTaskCanceled;

            //getting the AppServiceTriggerDetails and hooking up to the RequestReceived event
            var details = (AppServiceTriggerDetails)taskInstance.TriggerDetails;
            _appServiceConnection = details.AppServiceConnection;
            _appServiceConnection.RequestReceived += OnRequestReceived;
        }

The first step is to get a background task deferral. This allows the service to run asynchronous code against the background Task without crashing. The next step is to handle the background task’s Canceled event. Even if the Task get’s cancelled, we must complete the process and tell the OS that we have finished. If we won’t do this, the AppService will stop working on the first cancel operation. To do so, add this code to your Canceled event handling method:

            this._backgroundTaskDeferral?.Complete();

Last but not least, we need to handle the request that the AppService received. To do so, we need to get the AppServiceTriggerDetails from our BackgroundTask. This allows us to get  a reference to the AppServiceConnection, which provides the event ‘RequestReceived’ that we want to handle.

Within our RequestReceived event handling method, the effective work is done. As this is also an asynchronous action, we first need to get again a reference to the event’s Deferral:

var msgDeferral = args.GetDeferral();

The next step is to get the data from the event’s AppServiceRequestReceivedEventArgs:

            var input = args.Request.Message;

This gives us a ValueSet (which works like a Dictionary), which we need to parse to get the input data we need:

var response = (string) input["question"];

The ValueSet entries you are setting up here are the parameters your consumer has to provide. In my sample, I have only a single parameter called ‘question’, but it works also well with more parameters. After we pulled the parameters out of the ValueSet, we can do the work our AppService is supposed to do.

It is a good practice to separate the function you want to provide in the AppService in a separate project. You need to write the code only once, but can use it in your main application as well as in the AppService. In my Sample, this is done in the AppServiceResponder project. It may look like an overkill in this case, but if you have more complex logic than the sample it will absolutely make sense.

I am wrapping the work into a try/finally block as we need to complete the async operation in any case to keep our AppService running. This way, even if the work is not completed successfully, at least we come out clean of the AppService Task. Within the try part of the try/finally block, we are doing the work that the service is supposed to do. The result needs to be passed as a ValueSet again. To effectively send the result to the requesting app, we use this line of code:

await args.Request.SendResponseAsync(result);

Here is the full method for reference:

        private async void OnRequestReceived(AppServiceConnection sender, AppServiceRequestReceivedEventArgs args)
        {
            //async operation needs a deferral
            var msgDeferral = args.GetDeferral();


            //picking up the data ValueSet
            var input = args.Request.Message;
            var result = new ValueSet();

            //parsing the ValueSet
            var response = (string) input["question"];

            try
            {
                //as long as the app service connection is established we are using the same instance even if data changes.
                //to avoid crashes, clear the result before getting the new one
                result.Clear();

                if (!string.IsNullOrEmpty(response))
                {
                    var responderResponse = AppServiceResponder.Responder.Instance.GetResponse(response);

                    result.Add("Status", "OK");
                    result.Add("response", responderResponse);
                }

                await args.Request.SendResponseAsync(result);
            }
            //using finally because we need to tell the OS we have finished, no matter of the result
            finally
            {
                msgDeferral?.Complete();
            }
        }

Declaring the App Service in the host app

The final step we need to apply is to declare the AppService in our Package.appxmanifest. Declaring the AppService is pretty simple. Just select ‘App Service’ in the dropdown and hit ‘Add’. Give it a name (Microsoft recommends ‘reverse domain name style ‘,  so I used it. The last step is to declare the Entry point, which is AppServiceNamespace.ClassName (replace with yours).

The result should look like this:

image

Now build the solution. If all is set up correct, you have made an application implementing an AppService.

Creating the AppService Connector

Like I recommend to extract functionality that runs inside the AppService, I do so for the code that connects the app into a separate project. This allows you to reuse the project in multiple apps. An additional advantage is that you can create a Nuget package for this separate project to provide this functionality to other developers (I will write a separate post about this to keep this one focused on the AppService).

After adding a new project to the Solution, rename/replace also here Class1. I named my handler class just Connector. To make it a no brainer to use the connector, I implemented the class as singleton:

        private static Connector _instance;
        public static Connector Instance => _instance ?? (_instance = new Connector());

After that, I added an asynchronous Task that returns the AppService’s response. Let’s have a look inside the task. Inside the using statement for the AppServiceconnection, the first thing we need to do is to call the AppService with these three lines of code:

                //declaring the service and the package family name
                SampleAppServiceConnection.AppServiceName = "com.msiccdev.sampleappservice";

                //this one can be found in the Package.appxmanifest file
                SampleAppServiceConnection.PackageFamilyName = "acc75b1a-8b90-4f18-a2c4-08b0d700f1c6_62er76fr5b6k0";

                //trying to connect to he AppService
                AppServiceConnectionStatus status = await SampleAppServiceConnection.OpenAsync();

We’ll get a AppServiceConnectionStatus back, which helps us to deside how to go on in the task. If we do not have success in getting a connection to the AppService, I am returning an error description. For this, I created a simple helper method:

        private string GetStatusDetail(AppServiceConnectionStatus status)
        {
            var result = "";
            switch (status)
            {
                case AppServiceConnectionStatus.Success:
                    result = "connected";
                    break;
                case AppServiceConnectionStatus.AppNotInstalled:
                    result = "AppServiceSample seems to be not installed";
                    break;
                case AppServiceConnectionStatus.AppUnavailable:
                    result =
                        "App is currently not available (could be running an update or the drive it was installed to is not available)";
                    break;
                case AppServiceConnectionStatus.AppServiceUnavailable:
                    result = "App is installed, but the Service does not respond";
                    break;
                case AppServiceConnectionStatus.Unknown:
                    result = "Unknown error with the AppService";
                    break;
            }

            return result;
        }

For the case we are successful with our connection attempt , I am sending the needed ValueSet with these lines:

                    var input = new ValueSet() {{"question", question}};
                    AppServiceResponse response = await SampleAppServiceConnection.SendMessageAsync(input);

I am using a simple ValueSet with just one value here, but I have already done it with a more complex structure and this works as well. I haven’t reached any limits by now, but I think that they are the same as for all Background Tasks (don’t throw stones at me if it is different). The only thing I then need to do is to handle the response according to its status with this switch statement:

                    switch (response.Status)
                    {
                        case AppServiceResponseStatus.Success:
                            result = (string) response.Message["response"];
                            break;
                        case AppServiceResponseStatus.Failure:
                            result = "app service called failed, most likely due to wrong parameters sent to it";
                            break;
                        case AppServiceResponseStatus.ResourceLimitsExceeded:
                            result = "app service exceeded the resources allocated to it and had to be terminated";
                            break;
                        case AppServiceResponseStatus.Unknown:
                            result = "unknown error while sending the request";
                            break;
                    }

As we already know by know, we receive a ValueSet as response message. In my sample, I am returning only the response string. That’s it, we are already able to run use the AppService via the Connector. For demo purposes, I added also a simple AppService consumer app. Once the user puts in a question and hits the answer button, the result from the AppService gets displayed. All we need is just one line of code:

            AnswerTextBlock.Text = await SampleAppServiceConnector.Connector.Instance.GetResponse(QuestionTextBox.Text);

Pretty easy to use, right? Here is a screen shot from the consumer app:

image

That’s all we need for our AppService. Bonus of the project structure I used: You can provide a Nuget Package for other devs to consume your AppService. How? I will write about this in my next blog post.

Even if this is not a MVVM structured app, it absolutely works in there, too. If you want to have a look on a live in the Store app that uses MVVM and an AppService, click here. For using the AppService within your app, just download this Nuget Package into your app. Otherwise, I created a complete working sample and pushed it on my Github account right here. Feel free to play around with it to explore AppServices a bit more. As always, I hope this post is helpful for some of you.

Happy coding, everyone!

Posted by msicc in Dev Stories, UWP, win8dev, wpdev, 3 comments

How to create a RSS feed web tile with notifications for your Microsoft Band

This is a blog post not only for developers, but also for users (I will try to get not to technical in this post).  I managed to buy a Microsoft Band 2 for me here in Europe two weeks ago, and of course I am still exploring all the functionality that it has. A web tile is one of the cool features it supports – with a web tile, you can add your digital footprint to the Microsoft Band. And the best thing: you don’t need to be a developer to create your own! Microsoft provides a web kit that creates the tile for you!

Let’s have a look at the (not so hard to understand) steps it takes to create your own web tile:

The First step is to choose the layout, which also describes the type of the web tile:

Screenshot (82)

After selecting the feed tile template, you need to find the RSS url of your blog or other source site. Paste it in the desired field and hit the next button.

Screenshot (83)

Microsoft’s site now reads your RSS feed and provides you the single fields that come with your feed. When you hover with your mouse over the fields, they’’ll get highlighted. Just drag and drop them into the Microsoft Band preview image on the left hand side.

Screenshot (77)

Now that you have selected the data that should appear on the Microsoft Band, let’s set up the notification for the web tile. This is where it gets a bit tricky, but most feeds should be covered by the following image:

Screenshot (79)

No worries, I am telling you what is done here. The first and second line is the title and the description of the notification. You can put in there whatever you like. The most important part is the condition expression below the Band preview. Sadly the documentation provided by Microsoft is not as detailed for feed tiles as it should. Luckily, I found a post at StackOverflow that explains a little bit more. If you’re a developer, feel free to read the full text. If you are a user: just drag and drop the guid field of the “item” section into the first and also into the last field and set the condition to not equal. If your feed gets a new item, you will get a notification on your band with that. This condition looks if there is any new guid in the items list of your feed – and if so, sends out the notification and shows the badge.

In the last step, we just need to provide some details about the web tile we have created. If you want to have all features, you must provide both images:

Screenshot (80)

If you want to have control on how the image looks like, you should provide the images already flattened into a transparent and white image already. The result could look very creepy otherwise. After that, you have finally created your web tile – congratulations!

Screenshot (81)

Once you have downloaded the web tile, you just need to mail it to yourself or anyone who wants to use it. The other option is to put it on your OneDrive and just share a link to your web tile. To share the link you need to add the link of your online storage to this: “mshealth-webtile://?action=download-manifest&url=”. The web tile I created for my blog is in this case: mshealth-webtile://?action=download-manifest&url=http://1drv.ms/1TDRGSC . This link only works on phones (also Android and iOS). It opens the Microsoft Health app (that needs to be installed for the usage of web tiles, anyways) and asks you to install the web tile:

wp_ss_20160226_0001

Once you have done that, your web tile is ready to go. Once you have a new entry in your RSS feed, the notification should appear on your band. If you want to force the update, just force the Microsoft Health app to sync with your band. After that, you should see the notification and also the badge count. Here is a shot of the one I did for testing:

WP_20160226_17_48_20_Rich_LI

I only began to play around with web tiles, and already was able to create a pretty good result so far. As I will explore them more and more, I will continue to blog about it. In the meantime, I hope this blog post is helpful for some of you. Have fun, everybody!

Posted by msicc in Dev Stories, Microsoft Band, User Stories, Windows Phone, 1 comment

Review of 2015–my first year in Switzerland

2015 was once again a year where a lot happened. My year began with the start of a new job – I am now employed as a full time developer at the Swiss Shareholder register ShareCommService AG. The first days in Switzerland where full of trouble, as I needed to start from scratch in a new country. I found a room in a shared appartment, which was quite ok for me alone. Internet, phone, insurance, pass port – these were the things I had to do in the first weeks besides learning all the new things that you usually do when entering a new company.

timerarmvvmAs part of my new job, it was also heavily demanded that I finally get deeply into MVVM. I always read a lot about that, but avoided it because I wanted to get things done in my private projects. My MVVM learning project was a WPF timer app that supports resuming, multiple timers and more. I learned it in the only right way: without any frameworks/toolkits, which helps a lot to understand what is going on. Needless to say that I am happy to be past this point, as we are using MVVM Light a lot in our LOB applications. LOB (Line-of-Business) applications are different from what I have done before. They are used only internally and directly affect our daily business. I also learned more about SQL and databases, and also SignalR took a big part of my learning curve.

I have the luck to learn from Roman Müller, who has a gigantic amount of experience in programming and also has always some funny programming story to tell from his past. Together with Reto, the second programmer in our team, he teached me a lot – not only programming things, but also better ways to analyze and think about situations where you can end in programming. I am really thankful to be part of this team. Our system administrator Stefan, which I like to refer as a ‘BOFH with the heart on the right place’, makes the team complete.

During the year, I participated also in several Annual General Meetings (AGM) of our customers. This was very helpful for me to understand my new job, as we are responsible for all things regarding the votings on their agenda.

My first private project this year was to rewrite Voices Admin as a universal (Windows 8.1) app. Of course I did it as plain MVVM app, and it helped me a lot to get even deeper into it, and also boosted my learning curve in my daily job. I updated my UserVoice library as well to be fully portable in the meantime. Currently, I am working on the UWP version of UniShare.

voices admin

My family stayed in Germany for several private reasons in the first month of the year. Beginning in August, we moved completely to Switzerland. I am happy that we passed this point as my family is very important to me and is giving me a lot of power. I have to thank my wife and also both of my kids for their understanding, as being a programmer is often very time consuming.

I also discovered a completely new area: the Internet of Things. With the Rasperry Pi2 supporting the Windows 10 IoT Core, I played around with it, learned a few new things about building hardware – and build a prototype for internal testings.

raspi2proto

You see, I had a year full of action, and I tried to make this post as short as possible. I am looking forward to 2016, where my developer story will continue. I did also blog only a few things this year, and I am trying to keep things up and post more frequently next year.

For now, I whish everyone all the best for the end of this year and also for 2016!

Posted by msicc in Dev Stories, User Stories, 0 comments

How to implement a simple notification system in MVVM Windows 8.1 Universal apps

screenshot_07042015_152814

If your app performs actions, you most probably want to add also some confirmation if an action has finished. There are some ways to do this, like using local toast notifications or MessageDialogs. While I was working on Voices Admin v2, which is a universal app, I came along with a helper to simplify using local toast notifications. However, there came the point, where I got annoyed by the sound of these, and I looked into possible ways to replace them. My solution is a simple notification system, that uses the MVVM Light Messenger.

The first thing I did was adding a new property that broadcasts its PropertyChangedMessage to my ExtendedViewModelBase (which inherits from the MVVM Light ViewModelBase). This simplifies setting the notification text across multiple ViewModels as I don’t need to create a property in every ViewModel of my app:

public class ExtendedViewModelBase : ViewModelBase
    {
        public ExtendedViewModelBase()
        {
            
        }


        /// <summary>
        /// The <see cref="NotificationText" /> property's name.
        /// </summary>
        public const string NotificationTextPropertyName = "NotificationText";

        private string _notificationText = string.Empty;

        /// <summary>
        /// Sets and gets the NotificationText property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// This property's value is broadcasted by the MessengerInstance when it changes.
        /// </summary>
        public string NotificationText
        {
            get
            {
                return  _notificationText = string.Empty;
            }
            set
            {
                Set(() => NotificationText, ref _notificationText, value, true);
            }
        }
   }

The second step is to create the possibility to bind this into my view. I am using a custom PageBase class to simplify this. For those binding purposes it is common to add a DependencyProperty, and this is exactly what I did:

/// <summary>
        /// global property to bind the notification text against
        /// </summary>
        public static readonly DependencyProperty AppNotificationTextProperty = DependencyProperty.Register(
            "AppNotificationText", typeof (string), typeof (PageBase), new PropertyMetadata(string.Empty, (s, e) =>
            {
                var current = s as PageBase;

                if (current == null)
                {
                    return;
                }

                current.CheckifNotificationMessageIsNeeded(s);
            }));

        /// <summary>
        /// gets or sets the AppNotificationText
        /// </summary>
        public string AppNotificationText
        {
            get { return (string)GetValue(AppNotificationTextProperty); }
            set { SetValue(AppNotificationTextProperty, value); }}

You may have noticed that I hooked up into the PropertyChangedCallback of the DependecyProperty, which passes the execution to an separate method. Before we’ll have a look on that method, we need to add two private members to my PageBase: one for a StackPanel (mainly to set the Background color) and another one for Textblock. This is needed because this is the visible part of the notification. In the constructor of my PageBase class, I am filling them with live and connect them together:

            //instantiate and create StackPanel and TextBlock
            //you can put anything you want in the panel
            _panel = new StackPanel()
            {
                Background = new SolidColorBrush(Colors.Blue),
                Visibility = Visibility.Collapsed,
            };

            _textBlock = new TextBlock()
            {
                FontSize = 20,
                Margin = new Thickness(39, 10, 10, 10),
                TextAlignment = TextAlignment.Center
            };
            _panel.Children.Add(_textBlock);

The next thing we need to do is the FindChildren<T> helper method, which I took from the MSDN docs:

        /// <summary>
        /// Gets a list of DependencyObjects from the Visual Tree
        /// </summary>
        /// <typeparam name="T">the type of the desired object</typeparam>
        /// <param name="results">List of children</param>
        /// <param name="startNode">the DependencyObject to start the search with</param>
        public static void FindChildren<T>(List<T> results, DependencyObject startNode) where T : DependencyObject
        {
            int count = VisualTreeHelper.GetChildrenCount(startNode);
            for (int i = 0; i < count; i++)
            {
                var current = VisualTreeHelper.GetChild(startNode, i);
                if ((current.GetType()) == typeof(T) || (current.GetType().GetTypeInfo().IsSubclassOf(typeof(T))))
                {
                    T asType = (T)current;
                    results.Add(asType);
                }
                FindChildren<T>(results, current);
            }
         }

This helper enables us to find the top level grid, where we will add the StackPanel and control its visibilty and the TextBlock’s text. Which we are doing with the CheckifNotificationMessageIsNeeded() method:

        /// <summary>
        /// handles the visibility of the notification
        /// </summary>
        /// <param name="currentDependencyObject">the primary depenedency object to start with</param>
        private void CheckifNotificationMessageIsNeeded(DependencyObject currentDependencyObject)
        {
            if (currentDependencyObject == null) return;

            var children = new List<DependencyObject>();
            FindChildren(children, currentDependencyObject);
            if (children.Count == 0) return;

            var rootGrid = (Grid)children.FirstOrDefault(i => i.GetType() == typeof(Grid));

            if (rootGrid != null)

                if (!string.IsNullOrEmpty(AppNotificationText))
                {
                    if (!rootGrid.Children.Contains(_panel))
                    {
                        rootGrid.RowDefinitions.Add(new RowDefinition() {Height = new GridLength(_panel.ActualHeight, GridUnitType.Auto)});
                        _panel.SetValue(Grid.RowProperty, rootGrid.RowDefinitions.Count);

                        rootGrid.Children.Add(_panel);
                    }

                    _textBlock.Text = AppNotificationText;
                    _panel.Visibility = Visibility.Visible;
                }
                else if (string.IsNullOrEmpty(AppNotificationText))
                {
                    _textBlock.Text = string.Empty;
                    _panel.Visibility = Visibility.Collapsed;
                }
        }

Once we have the rootGrid on our Page, we are adding a new Row, set the StackPanel’s Grid.Row property to that and finally add the StackPanel to the Grid’s Children – but only if it does not exist already. No everytime the AppNotificationText property changes, the visibility of the StackPanel changes accordingly. Same counts for the TextBlock’s text. That’s all we need to do in the PageBase class.

The final bits of code we have to add are in the MainViewModel. I am using the MainViewModel as a kind of root ViewModel, which controls values and actions that are needed across multiple ViewModels. If you do not use it in the same way, you might need to write that code in all of your ViewModels where you want to use the notifications. The biggest advantage of my way is that the notification system (and other things) also works across pages.

The first thing we need is of course a property for the notification Text, which we will use to bind against on all pages where we want to use the notification system:

        /// <summary>
        /// The <see cref="GlobalNotificationText" /> property's name.
        /// </summary>
        public const string GlobalNotificationTextPropertyName = "GlobalNotificationText";

        private string _globalNotificationText = string.Empty;

        /// <summary>
        /// Sets and gets the GlobalNotificationText property.
        /// Changes to that property's value raise the PropertyChanged event. 
        /// </summary>
        public string GlobalNotificationText
        {
            get
            {
                return _globalNotificationText;
            }
            set
            {
                Set(() => GlobalNotificationText, ref _globalNotificationText, value);
            }
        }

Now we have this, we are hooking into the MVVM Messenger to catch the broadcasted NotificationText’s PropertyChangedMessage:

            Messenger.Default.Register<PropertyChangedMessage<string>>(this, message =>
            {
                if (message.PropertyName == ExtendedViewModelBase.NotificationTextPropertyName)
                {
                }
             });

If we would stop here, you would need to find a good point to set the NotificationText (and/or the GlobalNotificationText) property back to an empty string. This can be like the search a needle in the hay, believe me. That’s why I am giving every notification 5 seconds to be displayed, and the I am resetting the GlobalNotificationText  property in my MainViewModel automatically. To achieve this goal, I am using a simple DispatcherTimer with an Interval of 1 second:

            _notificationTimer = new DispatcherTimer() { Interval = new TimeSpan(0, 0, 1) };

DispatcherTimer has a Tick event, which fires every time a Tick happened. In our case, it fires every second. Hooking up into this event is essential, so add this line of code and let Visual Studio create the handler for you:

//in constructor:       
_notificationTimer.Tick += _notificationTimer_Tick;

//generated handler:
        private void _notificationTimer_Tick(object sender, object e)
        {
        }

Inside the Tick event handler, I am counting the ticks (using a private member in my MainViewModel). Once the timer passed 5 seconds, I am stopping the DispatcherTimer, reset the counter and finally set the GlobalNotificationText  property back to empty, which causes the notification to disappear:

            _notificationTimerElapsedSeconds++;

            if (_notificationTimerElapsedSeconds > 5)
            {
                _notificationTimer.Stop();
                _notificationTimerElapsedSeconds = 0;
                GlobalNotificationText = string.Empty;
            }

Of course we also need to start the DispatcherTimer. The perfect time for this is within the handler of the received PropertyChangedMessage we added earlier:

            //register for the global NotificationText PropertyChangedMessage from all VMs that derive from ExtendenViewModelBase
            Messenger.Default.Register<PropertyChangedMessage<string>>(this, message =>
            {
                if (message.PropertyName == ExtendedViewModelBase.NotificationTextPropertyName)
                {
                    if (!_notificationTimer.IsEnabled)
                    {
                        _notificationTimer.Start();
                    }
                    else
                    {
                        _notificationTimerElapsedSeconds = 0;
                    }

                    GlobalNotificationText = message.NewValue;
                }
            });

I am just checking if the DispatcherTimer is not yet enabled (= running) and start the timer in this case. If it is already running, I am just resetting my counter property to make sure that the notification is visible for 5 seconds again.

That’s it. Your MVVM (Light) app has now a simple and not so annoying notification system. It also provides the same experience across both platforms. There are sure ways to improve this here and there, that’s why I put up a sample to play around and contribute to on my Github account.

As always, I hope this post is helpful for some of you.

Happy coding!

Posted by msicc in Dev Stories, win8dev, wpdev, 0 comments

How to add Microsoft Application Insights v1 to your Windows 8.1 Universal app

Late in 2014, Microsoft finally started Application Insights (AI), their own telemetry service for all kind of apps. For Windows (Phone) 8.1 apps, the service was a long running beta. This month, Microsoft finally released version 1.0 of Application Insights for Windows apps.

Screenshot (15)

However, if you are upgrading from a previous version, you will see that AI will no longer send any data to Azure. This has a very simple reason. Microsoft moved the configuration from the former ApplicationInsights.config file to a class called WindowsAppInitializer. I only found this out because I commented at the corresponding documentation site, which causes Microsoft to send me an email with a link to the solution in the forums. You will not find these info in the documentation as of writing this blog post. Microsoft also updated the docs tonight.

I strongly recommend you to remove all old references in favor of just updating to avoid any glitches with the new API.

I played around with the new WindowsAppInitializer class. If you want to collect all data with the automatic WindowsCollectors, all you have to add to your code is one line in your App.xaml.cs constructor (Microsoft recommends to add it before all other code):

WindowsAppInitializer.InitializeAsync("your instrumentation key”);

That’s it. Really. Here’s a screen shot of the test app in Visual Studio I created to play around with the new WindowsAppInitializer class:

Screenshot (24)

As you can see, telemetry data gets written to the debug output, and with that, it will be submitted to your Azure account. If you do not want to use all Collectors, just add those you want to use after your InstrumentationKey, separated with ‘|’ in the IninitalizeAsync Method.

Adding custom telemetry data collection is still possible. Quick sample:

var tc = new TelemetryClient();
tc.TrackEvent("MainPage loaded... [WP TestEvent]");

This will send this string as a custom event to your Azure account. For more info about custom telemetry data, check this page.

As always, I hope this blog post is helpful for some of you.

Happy coding!

Posted by msicc in Dev Stories, win8dev, wpdev, 1 comment