|
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Controls;
- using System.Windows;
- using System.Xml.Linq;
- using System.Drawing;
- using System.Reflection;
-
- namespace BPA.UIControl
- {
- /// <summary>
- /// Panel 帮助类
- /// </summary>
- public class PanelHelper
- {
- /// <summary>
- /// 间距
- /// </summary>
- public static readonly DependencyProperty SpacingProperty = DependencyProperty.RegisterAttached(
- "Spacing", typeof(double), typeof(PanelHelper), new FrameworkPropertyMetadata(0d, FrameworkPropertyMetadataOptions.AffectsMeasure, OnSpacingChanged));
-
- public static double GetSpacing(DependencyObject obj)
- {
- return (double)obj.GetValue(SpacingProperty);
- }
-
- public static void SetSpacing(DependencyObject obj, double value)
- {
- obj.SetValue(SpacingProperty, value);
- }
-
- private static void OnSpacingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is Panel panel)
- {
- panel.SizeChanged -= Panel_SizeChanged;
- panel.SizeChanged += Panel_SizeChanged;
-
- if (panel.IsLoaded)
- {
- SetPanelChildrenSpacing(panel, null);
- }
- else
- {
- panel.Loaded += SetPanelChildrenSpacing;
- }
- }
- }
-
- private static void Panel_SizeChanged(object sender, SizeChangedEventArgs e)
- {
- SetPanelChildrenSpacing(sender, null);
- }
-
- private static void SetPanelChildrenSpacing(object sender, RoutedEventArgs e)
- {
- var panel = (Panel)sender;
- panel.Loaded -= SetPanelChildrenSpacing;
- switch (panel)
- {
- case StackPanel stackPanel:
- SetStackPanelSpacing(stackPanel);
- break;
-
- case Grid grid:
- SetGridSpacing(grid);
- break;
- }
- }
-
- private static void SetHorizontalSpacing(SpacingType type, FrameworkElement element, double spacing, Thickness oldMargin)
- {
- switch (type)
- {
- case SpacingType.No:
- default:
- element.Margin = new Thickness(0, oldMargin.Top, 0, oldMargin.Bottom);
- break;
- case SpacingType.Start:
- element.Margin = new Thickness(spacing / 2, oldMargin.Top, 0, oldMargin.Bottom);
- break;
- case SpacingType.End:
- element.Margin = new Thickness(0, oldMargin.Top, spacing / 2, oldMargin.Bottom);
- break;
- case SpacingType.All:
- element.Margin = new Thickness(spacing / 2, oldMargin.Top, spacing / 2, oldMargin.Bottom);
- break;
- }
- }
-
- private static void SetVerticalSpacing(SpacingType type, FrameworkElement element, double spacing, Thickness oldMargin)
- {
- switch (type)
- {
- case SpacingType.No:
- default:
- element.Margin = new Thickness(oldMargin.Left, 0, oldMargin.Right, 0);
- break;
- case SpacingType.Start:
- element.Margin = new Thickness(oldMargin.Left, spacing / 2, oldMargin.Right, 0);
- break;
- case SpacingType.End:
- element.Margin = new Thickness(oldMargin.Left, 0, oldMargin.Right, spacing / 2);
- break;
- case SpacingType.All:
- element.Margin = new Thickness(oldMargin.Left, spacing / 2, oldMargin.Right, spacing / 2);
- break;
- }
- }
-
- // StackPanel
- private static void SetStackPanelSpacing(StackPanel stackPanel)
- {
- var children = stackPanel.Children.OfType<FrameworkElement>().Where(x => x.Visibility != Visibility.Collapsed).ToList();
- var count = children.Count;
- var index = 0;
- foreach (FrameworkElement element in children)
- {
- var spacing = GetSpacing(stackPanel);
- SpacingType type;
- if (index == 0)
- {
- type = SpacingType.End;
- }
- else if (index == count - 1)
- {
- type = SpacingType.Start;
- }
- else
- {
- type = SpacingType.All;
- }
-
- if (stackPanel.Orientation == Orientation.Horizontal)
- {
- SetHorizontalSpacing(type, element, spacing, new Thickness(0));
- }
- else
- {
- SetVerticalSpacing(type, element, spacing, new Thickness(0));
- }
-
- index++;
- }
- }
-
- // Grid
- private static void SetGridSpacing(Grid grid)
- {
- var children = grid.Children.OfType<FrameworkElement>().Where(x => x.Visibility != Visibility.Collapsed).ToList();
- foreach (FrameworkElement element in children)
- {
- var spacing = GetSpacing(grid);
- var oldMargin = element.Margin;
-
- // 水平间距
- var column = Grid.GetColumn(element);
- var columnSpan = Grid.GetColumnSpan(element);
- var gridColumns = grid.ColumnDefinitions.Count;
- SpacingType type;
- if (gridColumns == 0)
- {
- type = SpacingType.No;
- }
- else if (column == 0)
- {
- type = SpacingType.End;
- }
- else if (column + columnSpan == gridColumns)
- {
- type = SpacingType.Start;
- }
- else
- {
- type = SpacingType.All;
- }
-
- SetHorizontalSpacing(type, element, spacing, oldMargin);
-
- // 垂直间距
- oldMargin = element.Margin;
- var row = Grid.GetRow(element);
- var rowSpan = Grid.GetRowSpan(element);
- var gridRows = grid.RowDefinitions.Count;
-
- if (gridRows == 0)
- {
- type = SpacingType.No;
- }
- else if (row == 0)
- {
- type = SpacingType.End;
- }
- else if (row + rowSpan == gridRows)
- {
- type = SpacingType.Start;
- }
- else
- {
- type = SpacingType.All;
- }
-
- SetVerticalSpacing(type, element, spacing, oldMargin);
- }
- }
- }
- }
-
- /// <summary>
- /// 间隔类型
- /// </summary>
- internal enum SpacingType
- {
- /// <summary>
- /// 无间隔
- /// </summary>
- No = 0,
-
- /// <summary>
- /// 后面间隔
- /// </summary>
- Start,
-
- /// <summary>
- /// 后面间隔
- /// </summary>
- End,
-
- /// <summary>
- /// 前后间隔
- /// </summary>
- All,
- }
|