博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MetroGridHelper: A helpful debugging assistant for designers and developers alike
阅读量:5951 次
发布时间:2019-06-19

本文共 9827 字,大约阅读时间需要 32 分钟。

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: ).

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,  and , 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  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:

PhoneMetro

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 ()
  • Install the package using the console or package manager. It is called 

    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{    ///     /// 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.    ///     public static class MetroGridHelper    {        private static bool _visible;        private static double _opacity = 0.15;        private static Color _color = Colors.Red;        private static List
_squares; private static Grid _grid; ///
/// Gets or sets a value indicating whether the designer grid is /// visible on top of the application's frame. /// public static bool IsVisible { get { return _visible; } set { _visible = value; UpdateGrid(); } } ///
/// Gets or sets the color to use for the grid's squares. /// public static Color Color { get { return _color; } set { _color = value; UpdateGrid(); } } ///
/// Gets or sets a value indicating the opacity for the grid's squares. /// public static double Opacity { get { return _opacity; } set { _opacity = value; UpdateGrid(); } } ///
/// Updates the grid (if it already has been created) or initializes it /// otherwise. /// 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(); } } ///
/// Builds the grid. /// private static void BuildGrid() { _squares = new List
(); 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; } } ///
/// 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. /// ///
The phone application frame. ///
The parent grid to insert the sub-grid into. 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

你可能感兴趣的文章
Linux报“Unknown HZ value! (288) Assume 100”错误
查看>>
mysql多实例实例化数据库
查看>>
我的友情链接
查看>>
golang xml和json的解析与生成
查看>>
小弟的新书《Ext JS权威指南》终于出版了
查看>>
好吧好吧,就在这里消磨时间
查看>>
二层的,DTP+CAM/ARP
查看>>
2011工作总结
查看>>
javascript 操作DOM元素样式
查看>>
Android 内存管理 &Memory Leak & OOM 分析
查看>>
[转]html5 Canvas画图教程(7)—canvas里画曲线之quadraticCurveTo方法
查看>>
[水]三个数学的小技巧题
查看>>
[leetcode-342-Power of Four]
查看>>
MongoDB3.0 创建用户
查看>>
2017-2018-1 20155319 《信息安全系统设计基础》第3周学习总结
查看>>
express 3.0.x 中默认不支持flash() 的解决方法
查看>>
uva-111-dp
查看>>
算法学习1——矩阵转置
查看>>
Tcl与Design Compiler (九)——综合后的形式验证
查看>>
跨页数据传递
查看>>