MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode

Because the left-margin is different for Snapped and Portrait mode, the previous version of MetroGridHelper for WinRT was not optimal. It didn’t support a different left margins at all. Don’t be sad, v1.1 supports Filled (120px), Snapped(20px), Fullscreen Landscape(100px) and Fullscreen Portrait(100px).

You can find the updated version on NuGet.

If you’re new to the MetroGridHelper for winrt you can execute the below command in the NuGet Package Manager Console:

PM> Install-Package WinRT.MetroGridHelper

If you have already installed the previous version you can also do the Update-Package command via the Package Manager Console:

PM> Update-Package WinRT.MetroGridHelper

Ah you want to see how it looks like?

screenshot_07252012_204328

screenshot_08032012_224037screenshot_08032012_223554

The code? Yes of course.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Windows.Graphics.Display;
using Windows.UI;
using Windows.UI.Core;
using Windows.UI.ViewManagement;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Shapes;

namespace MC.MetroGridHelper
{
    /// <summary>
    /// A utility class that overlays a designer-friendly grid on top of the
    /// application frame, for use similar to the performance counters in
    /// App.xaml.cs. The color and opacity are configurable. The grid contains
    /// a number of squares that are 24x24, offset with 12px gutters, and all
    /// 24px away from the edge of the device.
    /// </summary>
    public static class MetroGridHelper
    {
        private static bool _visible;
        private static double _opacity = 0.15;
        private static Color _color = Colors.Red;
        private static List<Shape> _shapes;
        private static Grid _grid;
        private static bool _eventsAttached;
        private static double _width;
        private static double _height;

        /// <summary>
        /// Gets or sets a value indicating whether the designer grid is
        /// visible on top of the application's frame.
        /// </summary>
        public static bool IsVisible
        {
            get { return _visible; }
            set
            {
                _visible = value;
                UpdateGrid();
            }
        }

        /// <summary>
        /// Gets or sets the color to use for the grid's squares.
        /// </summary>
        public static Color Color
        {
            get { return _color; }
            set
            {
                _color = value;
                UpdateGrid();
            }
        }

        /// <summary>
        /// Gets or sets a value indicating the opacity for the grid's squares.
        /// </summary>
        public static double Opacity
        {
            get { return _opacity; }
            set
            {
                _opacity = value;
                UpdateGrid();
            }
        }

        /// <summary>
        /// Updates the grid (if it already has been created) or initializes it
        /// otherwise.
        /// </summary>
        private static void UpdateGrid()
        {
            if (_shapes != null)
            {
                var brush = new SolidColorBrush(_color);
                foreach (Shape square in _shapes)
                {
                    square.Fill = brush;
                }
                if (_grid != null)
                {
                    _grid.Visibility = _visible ? Visibility.Visible : Visibility.Collapsed;
                    _grid.Opacity = _opacity;
                }
            }
            else
            {
                BuildGrid();
            }
        }

        /// <summary>
        /// Builds the grid.
        /// </summary>
        private static async void BuildGrid()
        {
            _shapes = new List<Shape>();

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

            DependencyObject child = VisualTreeHelper.GetChild(frame, 0);
            var childAsBorder = child as Border;
            var childAsGrid = child as Grid;
            if (childAsBorder != null)
            {
                // Not a pretty way to control the root visual, but I did not
                // want to implement using a popup.
                UIElement content = childAsBorder.Child;
                if (content == null)
                {
                    await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, BuildGrid);
                    return;
                }
                childAsBorder.Child = null;
                await Window.Current.Dispatcher.RunAsync(CoreDispatcherPriority.Normal,
                                                         () =>
                                                             {
                                                                 var newGrid = new Grid();
                                                                 childAsBorder.Child = newGrid;
                                                                 newGrid.Children.Add(content);
                                                                 PrepareGrid(newGrid);
                                                                 AttachEvents();
                                                             });
            }
            else if (childAsGrid != null)
            {
                PrepareGrid(childAsGrid);
                AttachEvents();
            }
            else
            {
                Debug.WriteLine("Dear developer:");
                Debug.WriteLine("Unfortunately the design overlay feature requires that the root frame visual");
                Debug.WriteLine("be a Border or a Grid. So the overlay grid just isn't going to happen.");
            }
        }

        private static void AttachEvents()
        {
            if (_eventsAttached)
                return;
            Window.Current.SizeChanged += (s, e) => BuildGridForCurrentView();
            DisplayProperties.OrientationChanged += s => BuildGridForCurrentView(); 
            _eventsAttached = true;
        }

        public static void CreateGrid()
        {
            IsVisible = true;
        }

        /// <summary>
        /// Does the actual work of preparing the grid once the parent frame is
        /// in the visual tree and we have a Grid instance to work with for
        /// placing the chilren.
        /// </summary>
        /// <param name="parent">The parent grid to insert the sub-grid into.</param>
        private static void PrepareGrid(Grid parent)
        {
            if (_grid == null)
            {
                _grid = new Grid
                            {
                                IsHitTestVisible = false,
                                Visibility = _visible ? Visibility.Visible : Visibility.Collapsed,
                                Opacity = _opacity,
                                CacheMode = new BitmapCache()
                            };
                parent.Children.Add(_grid);
            }
            BuildGridForCurrentView();
        }

        public static int GetMarginForCurrentView()
        {
            bool isSnapped = ApplicationView.Value == ApplicationViewState.Snapped;
            bool isPortrait = DisplayProperties.CurrentOrientation == DisplayOrientations.Portrait ||
                              DisplayProperties.CurrentOrientation == DisplayOrientations.PortraitFlipped;
            if (isSnapped)
                return 20;
            if (isPortrait)
                return 100;
            return 120;
        }

        public static void BuildGridForCurrentView()
        {
            // Places the grid into the visual tree. It is never removed once
            // being added.
            var frame = Window.Current.Content as Frame;
            if (frame == null)
                return;

            _width=Math.Max(_width, frame.ActualWidth);
            _height=Math.Max(_height, frame.ActualHeight);
            _grid.Children.Clear();
            _shapes.Clear();
            IEnumerable<Shape> shapes = GetGridShapesForMargin(_width, _height, GetMarginForCurrentView());
            foreach (Shape shape in shapes)
            {
                _grid.Children.Add(shape);
                _shapes.Add(shape);
            }
        }

        public static IEnumerable<Shape> GetGridShapesForMargin(double width, double height, int margin)
        {
            // To support both orientations, unfortunately more visuals need to
            // be used. An alternate implementation would be to react to the
            // orientation change event and re-draw/remove squares.
            var brush = new SolidColorBrush(_color);
            double max = Math.Max(width, height);

            const double strokeWidth = 2.0;

            var horizontalLine = new Line
                                     {
                                         IsHitTestVisible = false,
                                         Stroke = brush,
                                         X1 = 0,
                                         X2 = max,
                                         Y1 = 100 + (strokeWidth/2),
                                         Y2 = 100 + (strokeWidth/2),
                                         StrokeThickness = strokeWidth,
                                     };
            yield return horizontalLine;
            var horizontalLine2 = new Line
                                      {
                                          IsHitTestVisible = false,
                                          Stroke = brush,
                                          X1 = 0,
                                          X2 = max,
                                          Y1 = 140 + (strokeWidth/2),
                                          Y2 = 140 + (strokeWidth/2),
                                          StrokeThickness = strokeWidth,
                                      };
            yield return horizontalLine2;

            var verticalLine = new Line
                                   {
                                       IsHitTestVisible = false,
                                       Stroke = brush,
                                       X1 = margin - (strokeWidth / 2),
                                       X2 = margin - (strokeWidth / 2),
                                       Y1 = 0,
                                       Y2 = max,
                                       StrokeThickness = strokeWidth,
                                   };
            yield return verticalLine;

            var horizontalBottomLine = new Line
                                           {
                                               IsHitTestVisible = false,
                                               Stroke = brush,
                                               X1 = 0,
                                               X2 = max,
                                               Y1 = height - 130 + (strokeWidth/2),
                                               Y2 = height - 130 + (strokeWidth/2),
                                               StrokeThickness = strokeWidth,
                                           };
            _shapes.Add(horizontalBottomLine);
            var horizontalBottomLine2 = new Line
                                            {
                                                IsHitTestVisible = false,
                                                Stroke = brush,
                                                X1 = 0,
                                                X2 = max,
                                                Y1 = height - 50 + (strokeWidth/2),
                                                Y2 = height - 50 + (strokeWidth/2),
                                                StrokeThickness = strokeWidth,
                                            };
            _shapes.Add(horizontalBottomLine2);
            yield return horizontalBottomLine2;

            const int tileHeight = 20;

            for (int x = margin; x < /*width*/ max; x += (tileHeight*2))
            {
                for (int y = 140; y < /*height*/ max; y += (tileHeight*2))
                {
                    var rect = new Rectangle
                                   {
                                       Width = tileHeight,
                                       Height = tileHeight,
                                       VerticalAlignment = VerticalAlignment.Top,
                                       HorizontalAlignment = HorizontalAlignment.Left,
                                       Margin = new Thickness(x, y, 0, 0),
                                       IsHitTestVisible = false,
                                       Fill = brush,
                                   };
                    yield return rect;
                }
            }
        }
    }
}
  • Gravatar Javier Suárez Ruiz August 9th, 2012 at 18:21
    Thank you so much for sharing this helper. It has been very useful.
  • Gravatar Vans For Sale May 2nd, 2014 at 20:44
    The Palisades Vulc, a low cut, slip-on with shoelace detail, features premium canvas upper made with water-based inks and glues. The Palisade Vulc removable and washable UltraCush? Eco Footbed delivers an extra comfy fit and its ultra-flexible, waste-free Vans Shoes,Cheap Vans,Vans For Sale,Vans Shoes Outlet,Custom Vans Shoes,vans lindero grey seafoam evo,vans era guate<a href=" http://www.shoesvansonuk.com/palisades-vulc-shoes-stv-navyantique-white-vkbbcg8-p-947.html"/>Vans Shoes</a> Vans Palisades Vulc Shoes-Stv Navy/Antique White-VKBBCG8The Palisades Vulc, a low cut, slip-on with shoelace detail, features premium canvas upper made with water-based inks and glues. The Palisade Vulc removable and washable UltraCush? Eco Footbed delivers an extra comfy fit and its ultra-flexible, waste-freeThe Palisades Vulc, a low cut, slip-on with shoelace detail, features premium canvas upper made with water-based inks and glues. The Palisade Vulc removable and washable UltraCush? Eco Footbed delivers an extra comfy fit and its ultra-flexible, waste-free
  • The Rata Lo, a lace-up loafer part of the SurfSider line, features a premium canvas upper made with water-based inks and dyes. Its removable and washable UltraCush? Eco Footbed delivers an extra comfy fit and its ultra-flexible, waste-free rubber outsole Vans Shoes,Cheap Vans,Vans For Sale,Vans Shoes Outlet,Custom Vans Shoes,vans lindero grey seafoam evo,vans era guate<a href=" http://www.shoesvansonuk.com/rata-lo-shoes-cockatooscuba-vok3ca3-p-955.html"/>Vans Rata Lo Shoes-Cockatoo/Scuba-VOK3CA3</a> Vans Rata Lo Shoes-Cockatoo/Scuba-VOK3CA3The Rata Lo, a lace-up loafer part of the SurfSider line, features a premium canvas upper made with water-based inks and dyes. Its removable and washable UltraCush? Eco Footbed delivers an extra comfy fit and its ultra-flexible, waste-free rubber outsoleThe Rata Lo, a lace-up loafer part of the SurfSider line, features a premium canvas upper made with water-based inks and dyes. Its removable and washable UltraCush? Eco Footbed delivers an extra comfy fit and its ultra-flexible, waste-free rubber outsole
  • Gravatar Vans Shoes May 2nd, 2014 at 20:44
    Vans Chima Pro Black/White/Tan,mint lo pro vans,vans madero tiger stripe,vans shoes wholesale,custom vans Vans Shoes,Cheap Vans,Vans For Sale,Vans Shoes Outlet,Custom Vans Shoes,vans lindero grey seafoam evo,vans era guate<a href=" http://www.shoesvansonuk.com/vans-chima-pro-blackwhitetan-lh36659-p-551.html"/>Top Sale Vans Chima Pro Black/White/Tan Lh36659 </a> Top Sale Vans Chima Pro Black/White/Tan Lh36659 Where to buy an excellent shoes has troubled many people especialy thoses new online buyers, buy Top Sale Vans Chima Pro Black/White/Tan Lh36659 from our online store will always be your best choice!Where to buy an excellent shoes has troubled many people especialy thoses new online buyers, buy Top Sale Vans Chima Pro Black/White/Tan Lh36659 from our online store will always be your best choice!
  • Gravatar This Web page June 20th, 2014 at 05:53
    e liquide MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar 1997 ford explorer radio diagram June 21st, 2014 at 22:57
    Hi there would you mind letting me know which webhost you're
    using? I've loaded your blog in 3 different browsers and I must say this blog loads a lot faster then most.
    Can you recommend a good web hosting provider at a fair price?
    Cheers, I appreciate it!
  • Gravatar my latest blog post June 28th, 2014 at 03:40
    herbal vaporizer pen MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar go June 29th, 2014 at 14:56
    electronic cigarette MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar This Web site June 29th, 2014 at 22:25
    hermes evelyne messenger bag replica MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar their website July 3rd, 2014 at 02:18
    nicotine free electronic cigarettes MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar Recommended Reading July 3rd, 2014 at 06:31
    e liquid-usa MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar next July 4th, 2014 at 15:00
    masterbuilt electric smoker MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar visit your url July 22nd, 2014 at 08:10
    hermes handbag outlet sydney MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar visit the next website July 23rd, 2014 at 06:10
    hermes bags prices MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar this guy July 23rd, 2014 at 16:49
    hermes prices MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar replica hermes handbags from hong kong July 25th, 2014 at 18:32
    cheap hermes birkin bag MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar hermes bearn wallet July 25th, 2014 at 21:08
    fake hermes bag buy MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar fake used hermes bags for sale July 26th, 2014 at 23:02
    hermes discount store MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar birkin hermes colori 2012 July 27th, 2014 at 05:34
    replica hermes wallet MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar fake authentic hermes birkin handbags July 28th, 2014 at 00:03
    hermes bags replicas MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar Wholesale Hermes Replica July 28th, 2014 at 12:16
    Louis vuitton handbags outlet sale MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar His response July 28th, 2014 at 15:38
    Hermes scarf tying ideas MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar Super fast reply July 29th, 2014 at 05:15
    Hermes crocodile bags MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar This contact form July 30th, 2014 at 02:47
    The best hermes replica handbags MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar Real Hermes Dogon Wallet July 30th, 2014 at 06:31
    Hermes current worldwide prices MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC
  • Gravatar Authentic Birkin Bag Price July 31st, 2014 at 16:23
    MetroGridHelper for WinRT v1.1–Enhanced to work with Snapped and Portrait mode - Silverlight, WP7, .NET, C#, ASP.NET MVC Hermes Kelly Bag Price Australia <a href=" http://www.asantesana.se/css/scripts/0e4b32d7c0c44949aac14d398efa6eb2.asp">http://www.asantesana.se/css/scripts/0e4b32d7c0c44949aac14d398efa6eb2.asp</a>
  • Gravatar cheap jordan shoes September 23rd, 2014 at 10:39
    The new "Reich" wing republicans are fighting to give unrestricted control to their big business friends to add anything they want to our food supply that will increase their net profits. We now have an apathetic society that takes everything for granted.
    cheap jordan shoes http://plussallatnagyker.hu/libraries/contact.php?
  • Gravatar cheap jordan shoes September 23rd, 2014 at 10:40
    And he's right. You may disagree, but Nas is the best rapper alive, and with "Life is Good," he's got the year's top album, regardless of genre. That's about five to eight ounces of coffee, two bags of Lipton tea, or three cans of Coke. At this level of caffeine consumption, most people will experience some symptoms of caffeine withdrawal if they quit abruptly.One family member is enjoying the season of his life, however. Second son Scott went to Oral Roberts University to work for another former OSU Cowboy by the name of Bill Self. Turmoil in Iraq would have a larger impact on the region, where a crisis in Syria is taking on a more sectarian tone and Shi'ite Iran, Sunni Turkey and Sunni Arab Gulf states are looking to increase their influence. And Iraqi troops, said in a statement on Sunday that the crisis may lead to one party rule and hurt Maliki's reputation as a statesman..
    cheap jordan shoes http://www.radiovychod.sk/tmp/home.php?
  • Gravatar jordan sale September 23rd, 2014 at 10:40
    Streaming subscribers currently pay $7.99 a month, a plan introduced back in 2010. The company raised monthly fees for new subscribers in Ireland by one euro back in January, a change that it said had impact. At the Mai Hoa Center, home to the children who were turned away from school, a memorial display at the centre holds rows of urns with remains of former residents. Began providing AIDS drugs, "We used to have one or two funerals a day.
    jordan sale http://www.sykkel.as/modules/cart.php?
  • Gravatar jordan shoes on sale September 23rd, 2014 at 10:40
    The Founding Fathers became very wise after years of bickering and finally building consensus through compromise. They were able to anticipate many things that might threaten the great experiment that they were creating and for many years it was viewed as an experiment.
    jordan shoes on sale http://www.motorcitycomic.com/blog/faq.php?
  • Gravatar chaussure mariée louboutin pas cher September 24th, 2014 at 18:06
    wonderful publish, very informative. I'm wondering why the opposite experts of this sector don't realize this. You should continue your writing. I'm confident, you've a huge readers' base already!|
    chaussure mariée louboutin pas cher http://louboutinpascheravis.babyslowe.com/chaussure-marie-louboutin-pas-cher-c-17.html
  • Gravatar Quest Bars September 25th, 2014 at 02:42
    Hi everybody, here every person is sharing these kinds of
    know-how, so it's fastidious to read this blog, and I used to pay a quick visit
    this website everyday.
  • Gravatar best dating sites October 14th, 2014 at 22:33
    Having read this I thought it was very informative. I appreciate you spending some time and effort to put this short article together.
    I once again find myself personally spending a significant amount of time both
    reading and leaving comments. But so what, it was still worthwhile!
  • Gravatar hombres buscan mujeres November 18th, 2014 at 01:54
    It's an remarkable article for all the internet users; they will take advantage from it I am sure.
  • Gravatar dinero urgente February 27th, 2015 at 13:55
    Thanks on your marvelous posting! I definitely enjoyed
    reading it, you might be a great author.I will make sure
    to bookmark your blog and may come back from now on. I want to encourage
    you to ultimately continue your great writing, have
    a nice day!
    dinero urgente
  • Gravatar Brayden May 22nd, 2015 at 14:04
    That is really fascinating, You're a very skilled blogger.
    I've joined your rss feed and sit up for looking for extra
    of your fantastic post. Also, I've shared your website in my social
    networks
    webpage (Brayden)
  • Gravatar 环保清洁用品 February 18th, 2016 at 09:23
    艾可力清洁膏
  • Gravatar fotbollströjor March 7th, 2016 at 18:27
    [url= http://www.borringebarnen.se/?m=201509]fotbollströjor[/url] V&auml;lj dina egna Arsenal nr.12 fotbollsspelare p&aring; [url= http://thewat.com/shop/]billiga fotbollströjor[/url] Olivier Giroud Tr&ouml;jor \n
  • Gravatar matchtröjor fotboll March 7th, 2016 at 18:28
    [url= http://tapaslinkoping.se/Real-Madrid/]matchtröjor fotboll[/url] Snabb leverans och b&auml;sta priser f&ouml;r Barcelon a [url= http://www.citywoodfloors.co.uk/wooden-doors/]fotbollströjor barn[/url] tr&ouml;ja barn \n
  • Gravatar Fotbollströjor July 5th, 2016 at 14:54
    Fotbollströjor http://www.nordtruck.se/docs/everton-44178.aspx Fotbollströjor http://www.nordtruck.se/docs/atletico-madrid-27880.aspx Real madrid tröja http://www.nordtruck.se/docs/real-madrid-42898.aspx Frankrike tröja http://www.nordtruck.se/docs/frankrike-31338.aspx Fotbollströjor http://www.nordtruck.se/docs/hamburger-32244.aspx
  • Gravatar BHW April 13th, 2017 at 02:12
    If you are going for best contents like myself, simply go to see this website everyday because
    it provides feature contents, thanks
  • Gravatar Juli May 7th, 2017 at 21:05
    Glad to be one of several visitants on this amazing internet
    site :D.
Gravatar