MetroGridHelper performance with Windows 8.1

MetroGridHelper performance with Windows 8.1

MetroGridHelper is a small helper class for XAML WinRT apps developed by Mark Monster which helps build perfectly aligned apps. As far as I remember, the idea for a metro grid helper goes back to early Windows Phone 7 development and a version for Windows Phone by Jeff Wilcox (Mark also credits him in his blog post). I've been noticing performance issues with it in Windows 8.1 apps during loading. Basically, splashscreen stays on much longer. Even though you should only be using MetroGridHelper while testing your apps so it won't make you fail during certification, it can still be somewhat annoying if you're testing your app a lot. If you're seeing the same issue - here's how to fix it!

MetroGridHelper performance in Windows 8.1 appsIf you look into the source code of the class, you'll notice that very soon after calling

MetroGridHelper.CreateGrid();  

it blocks until the Window.Current.Content Frame is not null and has children, like this:

private static async void BuildGrid()  
{
    var frame = Window.Current.Content as Frame;
    if (frame == null || VisualTreeHelper.GetChildrenCount(frame) == 0)
    {
        await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, BuildGrid);
        return;
    }

This condition is met when the Window gets activated, so instead of calling CreateGrid() at the end of the OnLaunched method in App.xaml.cs like it's suggested:

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

if (System.Diagnostics.Debugger.IsAttached)  
{
    MetroGridHelper.CreateGrid();
}

you can attach an event handler for Window.Current.Activated event instead, and call CreateGrid when the Window is actually Activated. So, put this at the end of OnLaunched method:

Window.Current.Activated += Window_Activated;  
// Ensure the current window is active
Window.Current.Activate();  

and then call CreateGrid() in Window_Activated.

void Window_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)  
{
   if (System.Diagnostics.Debugger.IsAttached)
   {
       MetroGridHelper.CreateGrid();
   }
}

This significantly improved loading times for me and hopefully will solve MetroGridHelper performance issues for you, too!

What if you're using Prism for WinRT?

If you're using Prism for WinRT, you probably know that the App.xaml.cs is different - a lot of the usual initialization code has been moved to MvvmAppBase inside the Prism framework. Still, the OnLaunched method exists even though you don't see the Window.Current.Activate() call! When overriding it, you can just attach an event handler for Window.Current.Activated and call CreateGrid() from there:

protected async override void OnLaunched(LaunchActivatedEventArgs args)  
{
    Windows.UI.Xaml.Window.Current.Activated += Window_Activated;
    ....

Window_Activated does the same thing as shown above.

If you're developing WinRT apps - you probably want them to be pixel-perfect. If you have doubts that it is, just use this great little helper class - it's available on NuGet and it's incredibly useful!

Igor Ralic

igor ralic

View Comments
Microsoft Certified Solutions Developer: Windows Store Apps in C#