You’ve heard me preach it before: fix those margins, align, and try and make your apps as beautiful and inspiring as you can (see also: my designer tips for developers).

On Thursday, I stopped by the Windows Phone Design Team’s beautiful studio space here on campus. It’s a really creative space, packed with fun people, chill music, and a genuine desire to see even better, more beautiful apps in the marketplace.

While sitting with two of the UX designers, Corrina and Arturo, and talking about some of these design principles, I just happened to be introduced to a nifty, albeit simple, gridline/grid that the team’s been using for some time while working on the Windows Phone. It’s just a set of red squares, 25×25 pixels, offset 12 pixels from one another, and all contained within a page padding of 24px. (Again: the magical Metro number is 12-based on those edges)

The design typically will use a Photoshop layer containing these squares, or maybe some XAML inserted on top of a page in an app, to work on alignment, visualizing the grid, etc., and making tweaks.

I got to thinking: it would be nice if this could be just like the performance counters that we have for the Windows Phone: at debug time, you could opt into overlaying this grid on top of the frame of the entire app, being omnipresent. I coded up a quick implementation during that meeting and here it is!

To use the counter, simply open up the App.xaml.cs file (where the other performance counters are) and add this in. I’d recommend just enabling it when you want to do a quick design pass. You can use this then both with apps on your phone as well as the emulator; it’s helpful in the emulator since you can then screenshot the UI and share that with your friends and family who can critique you on your pixel placement.

?
// Show graphics profiling information while debugging.
if (System.Diagnostics.Debugger.IsAttached)
{
    // Display the current frame rate counters.
    Application.Current.Host.Settings.EnableFrameRateCounter = true;
    // Display the metro grid helper.
    MetroGridHelper.IsVisible = true;

Here’s what it looks like at runtime in a very simple app:

In this example, I have one of the classic Windows Phone design “bugs”: one of the TextBlocks has just been inserted, without using the appropriate standard phone style. As a result, it has a Margin value of “0” instead of being 12 pixels offset from the left. It’s more clear now with the squares, since you can see the misalignment easily.

I’ve also added simple static properties for Opacity and Color if you’d rather not use the Red default color and ~0.15 opacity on the squares. The IsVisible property can be flipped off at runtime, but beware that the grid is still present in the visual tree once you add it – so there will be a performance hit (don’t ship an app that uses the grid in release builds).

Get the source

I’ve published the source file on NuGet – that’s a really easy way to get the file into your project, and if I make any fixes or add features in the future, it’ll be easy for you to get those changes:

  • Make sure you have NuGet installed (http://www.nuget.org/)
  • Install the package using the console or package manager. It is called MetroGridHelper

    PM> Install-Package MetroGridHelper

Or you can drop this source code into a new file of your project, MetroGridHelper.cs:

// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.using System.Collections.Generic;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;namespace System.Windows
{/// <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<Rectangle> _squares;private static Grid _grid;/// <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 (_squares != null){var brush = new SolidColorBrush(_color);foreach (var square in _squares){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 void BuildGrid(){_squares = new List<Rectangle>();var frame = Application.Current.RootVisual as Frame;if (frame == null || VisualTreeHelper.GetChildrenCount(frame) == 0){Deployment.Current.Dispatcher.BeginInvoke(BuildGrid);return;}var 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.var content = childAsBorder.Child;if (content == null){Deployment.Current.Dispatcher.BeginInvoke(BuildGrid);return;}childAsBorder.Child = null;Deployment.Current.Dispatcher.BeginInvoke(() =>{Grid newGrid = new Grid();childAsBorder.Child = newGrid;newGrid.Children.Add(content);PrepareGrid(frame, newGrid);});}else if (childAsGrid != null){PrepareGrid(frame, childAsGrid);}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.");return;}}/// <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="frame">The phone application frame.</param>/// <param name="parent">The parent grid to insert the sub-grid into.</param>private static void PrepareGrid(Frame frame, Grid parent){var brush = new SolidColorBrush(_color);_grid = new Grid();_grid.IsHitTestVisible = false;// 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.double width = frame.ActualWidth;double height = frame.ActualHeight;double max = Math.Max(width, height);for (int x = 24; x < /*width*/ max; x += 37){for (int y = 24; y < /*height*/ max; y += 37){var rect = new Rectangle{Width = 25,Height = 25,VerticalAlignment = System.Windows.VerticalAlignment.Top,HorizontalAlignment = System.Windows.HorizontalAlignment.Left,Margin = new Thickness(x, y, 0, 0),IsHitTestVisible = false,Fill = brush,};_grid.Children.Add(rect);_squares.Add(rect);}}_grid.Visibility = _visible ? Visibility.Visible : Visibility.Collapsed;_grid.Opacity = _opacity;// For performance reasons a single surface should ideally be used// for the grid._grid.CacheMode = new BitmapCache();// Places the grid into the visual tree. It is never removed once// being added.
            parent.Children.Add(_grid);}}
}

转载于:https://www.cnblogs.com/Yukang1989/archive/2013/01/18/2866160.html

MetroGridHelper: A helpful debugging assistant for designers and developers alike相关推荐

  1. 原型图 线框图_16个原型设计和线框图设计工具

    原型图 线框图 8. Balsamiq样机 (8. Balsamiq Mockups) Balsamiq Mockups (price:$US79, demo available) is an int ...

  2. 项目管理工具 web_14个用于改善项目的Web工具

    项目管理工具 web Here you can find the best services on the internet that will enhance your digital work a ...

  3. 图片转换为css_快速将色彩理论转换为CSS

    图片转换为css 重点 (Top highlight) Color is an extremely strong tool that we can apply to solve many design ...

  4. 数据库约束查找的约束_数据库约束的好处,成本和文档

    数据库约束查找的约束 Constraints exist as a way to enforce or document rules within the database. How do they ...

  5. 12 Essential Bootstrap Tools for Web Designers

    12 Essential Bootstrap Tools for Web Designers Posted by vikas on June 6, 2014, filed in: Tools, Web ...

  6. 使用 ftrace 调试 Linux 内核【转】

    转自:http://blog.csdn.net/adaptiver/article/details/7930646 使用 ftrace 调试 Linux 内核,第 1 部分 http://blog.c ...

  7. 从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误

    从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误 微软官方的解释(http://msdn2.microsoft.com/zh-cn/library/0htdy ...

  8. gluoncv 训练自己的数据集,进行目标检测

    跑了一晚上的模型,实在占GPU资源,这两天已经有很多小朋友说我了.我选择了其中一个参数. https://github.com/dmlc/gluon-cv/blob/master/scripts/de ...

  9. PInvoke调用导致堆栈不对称

    在SendMessage()时出错,原因:.net2.0 中加入了(Managed debugging assistant),在平台调用时检查栈的指针,如果发现不平衡,就会抛出PInvokeImbal ...

最新文章

  1. python发明者叫什么-看看9种编程语言的发明者是怎么说的
  2. 从python存入的文件是乱码_如何解决python写入html文件中乱码的现象(图文详解)...
  3. 使用ldirectord实现后端RS健康状态监测及LVS调度功能
  4. 数据管理与商业智能_商业智能与数据科学
  5. exp.validate.js
  6. 附录-实模式下1M内存
  7. java几次,java兑现限制用户几次登录
  8. 思科CCNA电子教程
  9. Linux下为空白SD卡建立BOOT,rootfs分区
  10. 海底捞成功的全套培训体系(收藏)
  11. tungsten-replicator安装
  12. 网络通信技术--设置IP地址
  13. 推荐一个免费的PDF在线编辑网站
  14. json.stringify()详解
  15. python爬虫 爬取评论区
  16. php 微博获取粉丝,新浪API,提取微博账号的信息,粉丝数、微博数等
  17. 基于SSM实现企业生资源管理系统-ERP系统
  18. a 是指计算机的什么应用,计算机中AtoC是什么应用软件
  19. 使用org.apache.pdfbox 2.x PDF 转Doc 转图片 转字符串
  20. 20-ICE_ITMC-WiFi-based_In-home_Fall-detection_Utility_Application_of_WiFi_Channel_State_Information_

热门文章

  1. Android中文API-ViewStub
  2. Android社会化分享详解
  3. Windows Socket和Linux Socket编程的区别
  4. C#实现清理系统内存
  5. code point,code unit
  6. MYSQL-skip-networking
  7. URL 路径长度限制(错误:指定的文件或文件夹名称太长)
  8. 请设计各种管理系统、业务系统的大哥大姐们,设计新系统时,拜托您,请允许我修改用户名、密码...
  9. 独家 | 蚂蚁金服TRaaS技术风险防控平台解密
  10. OOD之问题空间到解空间—附FP的建模