//////////////////////////////////////////////////////////////////////////////// // MiniGrid. An extension to WPF's Grid. // http://codefornothing.wordpress.com/2010/01/24/minifying-wpf-the-minigrid/ // // Copyright (c) 2010 Jose Simas (josesimas at gepsoft.com). All Rights Reserved. // // Permission to use, copy, modify, and distribute this software and its // documentation for any purpose, without fee, and without a written // agreement, is hereby granted, provided that the above copyright notice, // this paragraph and the following two paragraphs appear in all copies, // modifications, and distributions. // // IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, // INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST // PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, // EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF // ANY, PROVIDED HEREUNDER IS PROVIDED "AS IS". THE AUTHOR HAS NO OBLIGATION // TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. // // V1.0 24/01/2009 - First Release. //////////////////////////////////////////////////////////////////////////////// namespace Minify.WPF { using System; using System.Text.RegularExpressions; using System.Windows; using System.Windows.Controls; public class MiniGrid : Grid { public static readonly DependencyProperty ColumnsPatternProperty = DependencyProperty.Register("ColumnsPattern", typeof(string), typeof(MiniGrid), new PropertyMetadata(default(string), StructureChanged)); public static readonly DependencyProperty RowsPatternProperty = DependencyProperty.Register("RowsPattern", typeof(string), typeof(MiniGrid), new PropertyMetadata(default(string), StructureChanged)); private static void StructureChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) { var instance = (MiniGrid)source; instance.StructureChanged(); } public static readonly DependencyProperty VisibleProperty = DependencyProperty.Register("Visible", typeof(bool), typeof(MiniGrid), new PropertyMetadata(default(bool), VisibleChanged)); private static void VisibleChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) { var instance = (MiniGrid)source; instance.VisibleChanged(); } private void VisibleChanged() { Visibility = Visible ? Visibility.Visible : Visibility.Collapsed; } /// /// Traditional true/false visibility. Uses Collapsed for not visible. /// public bool Visible { get { return (bool)GetValue(VisibleProperty); } set { SetValue(VisibleProperty, value); } } #region Structure Processing /// /// A pattern the determines the type of rows and /// the number of rows of the Grid. /// /// The pattern can have any number of * character or a character. /// The character * creates a row with Height Star whereas the /// the character a creates a row with Height set to Auto. /// /// For example: a*a creates three rows, the first is Auto, /// the second is Star and the last one is also Auto. /// public string RowsPattern { get { return (string)GetValue(RowsPatternProperty); } set { SetValue(RowsPatternProperty, value); } } /// /// A pattern the determines the type of columns and /// the number of columns of the Grid. /// /// The pattern can have any number of * character or a character. /// The character * creates a column with Width Star whereas the /// the character a creates a column with Width set to Auto. /// /// For example: a*a creates three columns, the first is Auto, /// the second is Star and the last one is also Auto. /// public string ColumnsPattern { get { return (string)GetValue(ColumnsPatternProperty); } set { SetValue(ColumnsPatternProperty, value); } } /// /// Detect the type of the pattern and route to the /// correct construction method. /// private void StructureChanged() { RowDefinitions.Clear(); ColumnDefinitions.Clear(); if (RowsPattern == null) CreateRows(); else if (Regex.IsMatch(RowsPattern, " [0-9]+")) CreateProportionalRows(); else CreateRows(); if (ColumnsPattern == null) CreateColumns(); else if (Regex.IsMatch(ColumnsPattern, " [0-9]+")) CreateProportionalColumns(); else CreateColumns(); } /// /// Create rows using a numeric value. /// private void CreateProportionalRows() { foreach (var t in RowsPattern.Split(' ')) AddRow(Convert.ToDouble(t), GridUnitType.Pixel); } /// /// Create rows using a numeric value. /// private void CreateProportionalColumns() { foreach (var t in ColumnsPattern.Split(' ')) AddColumn(Convert.ToDouble(t), GridUnitType.Pixel); } /// /// Create the columns using Star or Auto. /// private void CreateColumns() { var colPattern = string.IsNullOrEmpty(ColumnsPattern) ? "*" : ColumnsPattern; foreach (var chr in colPattern.ToCharArray()) switch (chr) { case '*': AddColumn(Int32.MaxValue, GridUnitType.Star); break; case 'A': case 'a': AddColumn(Int32.MaxValue, GridUnitType.Auto); break; } } /// /// Create the rows using Star or Auto. /// private void CreateRows() { var rowPattern = string.IsNullOrEmpty(RowsPattern) ? "*" : RowsPattern; foreach (var chr in rowPattern.ToCharArray()) switch (chr) { case '*': AddRow(Int32.MaxValue, GridUnitType.Star); break; case 'A': case 'a': AddRow(Int32.MaxValue, GridUnitType.Auto); break; } } private void AddRow(double height, GridUnitType type) { RowDefinitions.Add(new RowDefinition { Height = new GridLength(height, type) }); } private void AddColumn(double width, GridUnitType type) { ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(width, type) }); } #endregion } }