using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Media; namespace UILib.DpUtil { public class GridHelper { #region Space public static double GetSpace(DependencyObject obj) { return (double)obj.GetValue(SpaceProperty); } public static void SetSpace(DependencyObject obj, double value) { obj.SetValue(SpaceProperty, value); } public static readonly DependencyProperty SpaceProperty = DependencyProperty.RegisterAttached("Space", typeof(double), typeof(Grid), new PropertyMetadata(0d, OnSpaceChanged)); public static string GetSpaceIgnore(DependencyObject obj) { return (string)obj.GetValue(SpaceIgnoreProperty); } public static void SetSpaceIgnore(DependencyObject obj, string value) { obj.SetValue(SpaceIgnoreProperty, value); } public static readonly DependencyProperty SpaceIgnoreProperty = DependencyProperty.RegisterAttached("SpaceIgnore", typeof(string), typeof(Grid), new PropertyMetadata(null, OnSpaceChanged)); private static void OnSpaceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is Grid grid) { if (e.Property == SpaceProperty) { grid.Loaded += GridSpaceOnLoaded; return; } } } private static void GridSpaceOnLoaded(object sender, RoutedEventArgs e) { if (!(sender is Grid grid)) return; RefreshGridSpace(grid); grid.Loaded -= GridSpaceOnLoaded; } public static void RefreshGridSpace(Grid grid) { double space = GetSpace(grid); if (space <= 0) { return; } bool ignoreTop = false, ignoreBottom = false, ignoreLeft = false, ignoreRight = false; string baseData = GetSpaceIgnore(grid) ?? ""; if (baseData.Contains("ALL")) { ignoreTop = true; ignoreBottom = true; ignoreLeft = true; ignoreRight = true; } if (baseData.Contains("LEFT")) { ignoreLeft = true; } if (baseData.Contains("RIGHT")) { ignoreRight = true; } if (baseData.Contains("TOP")) { ignoreTop = true; } if (baseData.Contains("BOTTOM")) { ignoreBottom = true; } var rowCount = grid.RowDefinitions.Count; rowCount = rowCount <= 0 ? 1 : rowCount; var columnCount = grid.ColumnDefinitions.Count; columnCount = columnCount <= 0 ? 1 : columnCount; int totalCount = rowCount * columnCount; if (grid.Children == null) return; foreach (FrameworkElement cell in grid.Children) { int row = Grid.GetRow(cell); int col = Grid.GetColumn(cell); int rowSpan = Grid.GetRowSpan(cell); int colSpan = Grid.GetColumnSpan(cell); double left = (col == 0 && ignoreLeft) ? 0 : space; double top = (row == 0 && ignoreTop) ? 0 : space; double right = ignoreRight ? 0 : ((col + colSpan == columnCount) ? space : 0); double bottom = ignoreBottom ? 0 : ((row + rowSpan == rowCount) ? space : 0); cell.Margin = new Thickness(left, top, right, bottom); //cell.Margin = new Thickness(space, // space, // (col + colSpan) == columnCount ? space : 0, // (row + rowSpan) == rowCount ? space : 0); } } #endregion public static Brush GetInnerBorderBrush(Grid obj) { return (Brush)obj.GetValue(InnerBorderBrushProperty); } public static void SetInnerBorderBrush(Grid obj, Brush value) { obj.SetValue(InnerBorderBrushProperty, value); } public static readonly DependencyProperty InnerBorderBrushProperty = DependencyProperty.RegisterAttached("InnerBorderBrush", typeof(Brush), typeof(GridHelper), new PropertyMetadata(null, OnInnerBorderChanged)); public static double GetInnerBorder(Grid obj) { var sb = obj.GetValue(InnerBorderProperty); return double.Parse(sb.ToString()); } public static void SetInnerBorder(Grid obj, object value) { double dv = double.Parse(value.ToString()); obj.SetValue(InnerBorderProperty, dv); } public static readonly DependencyProperty InnerBorderProperty = DependencyProperty.RegisterAttached("InnerBorder", typeof(object), typeof(GridHelper), new PropertyMetadata(0, OnInnerBorderChanged)); public static string GetInnerBorderIgnore(Grid obj) { return (string)obj.GetValue(InnerBorderIgnoreProperty); } public static void SetInnerBorderIgnore(Grid obj, string value) { obj.SetValue(InnerBorderIgnoreProperty, value); } public static readonly DependencyProperty InnerBorderIgnoreProperty = DependencyProperty.RegisterAttached("InnerBorderIgnore", typeof(string), typeof(GridHelper), new PropertyMetadata("None", OnInnerBorderChanged)); private static void OnInnerBorderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if (d is Grid grid) { if (e.Property == InnerBorderProperty || e.Property == InnerBorderIgnoreProperty) { grid.Loaded += GridInnerBorder_Loaded; return; } } } private static void GridInnerBorder_Loaded(object sender, RoutedEventArgs e) { Grid grid = sender as Grid; RefreshGridInnerBorder(grid); grid.Loaded -= GridInnerBorder_Loaded; } public static void RefreshGridInnerBorder(Grid grid) { double width = GetInnerBorder(grid); if (width <= 0) return; var rowCount = grid.RowDefinitions.Count; var columnCount = grid.ColumnDefinitions.Count; int totalCount = rowCount * columnCount; string baseData = GetInnerBorderIgnore(grid); HashSet data = new HashSet(baseData.Split(',')); bool ignoreTop = data.Contains("All") || data.Contains("Top"), ignoreBottom = data.Contains("All") || data.Contains("Bottom"), ignoreLeft = data.Contains("All") || data.Contains("Left"), ignoreRight = data.Contains("All") || data.Contains("Right"); foreach (var child in grid.Children) { if (child is Control control) { Thickness bt; Brush bb = GetInnerBorderBrush(grid) ?? Brushes.Black; if (GetSpace(grid) > width) { bt = new Thickness(width); } else { int row = Grid.GetRow(control), col = Grid.GetColumn(control), rowSpan = Grid.GetRowSpan(control), colSpan = Grid.GetColumnSpan(control); double left = (col == 0 && ignoreLeft) ? 0 : width; double top = (row == 0 && ignoreTop) ? 0 : width; double right = ignoreRight ? 0 : ((col + colSpan == columnCount) ? width : 0); double bottom = ignoreBottom ? 0 : ((row + rowSpan == rowCount) ? width : 0); bt = new Thickness(left, top, right, bottom); } control.BorderBrush = bb; control.BorderThickness = bt; } } } } }