新建wpf页面DataGridAutoView
引用空间: xmlns:ga="clr-namespace:WPFDemoMVVM.Helpers"- <Window x:
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
- xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:local="clr-namespace:WPFDemoMVVM.View"
- xmlns:ga="clr-namespace:WPFDemoMVVM.Helpers"
- mc:Ignorable="d"
- Title="DataGridAutoView" Height="450" Width="800">
- <Grid>
- <Grid ga:GridAssist.AutoRowColumn="_,2">
- <Grid.Resources>
-
-
- </Grid.Resources>
- <Label Content="IP Address"></Label>
- <TextBox Text="127.0.0.1"></TextBox>
- <Label Content="Port"></Label>
- <TextBox Text="8080"></TextBox>
- <Label Content="TimeOut"></Label>
- <TextBox Text="10000"></TextBox>
- </Grid>
- </Grid>
- </Window>
复制代码 新建一个类GridAssist
在定名空间clr-namespace:WPFDemoMVVM.Helpers下,新建GridAssist类- static class GridAssist
- {
- #region AutoRowColumn
- public static string GetAutoRowColumn(DependencyObject obj)
- {
- return (string)obj.GetValue(AutoRowColumnProperty);
- }
- public static void SetAutoRowColumn(DependencyObject obj, string value)
- {
- obj.SetValue(AutoRowColumnProperty, value);
- }
- /// <summary>
- /// 自动排列 Grid 容器中的所有控件
- /// </summary>
- /// <remarks>
- /// 值为一个逗号隔开的字符串,形如:<br/>
- /// - 2,3(2 行 3 列,列宽默认为 1*,行高为 Auto)<br/>
- /// - _,3(3 列,行数根据子控件而定)<br/>
- /// - 2,3,Auto(列的宽度为 Auto)<br/>
- /// Grid 中的所有控件将自动按照从左到右、从上到下的顺序进行排列<br/>
- /// 控件各自的 RowSpan 以及 ColumnSpan 也会被考虑
- /// </remarks>
- /// <example>
- ///
- /// <![CDATA[
- /// <Window xmlns:ap="clr-namespace:NemoDemo.AttachedProperties">
- /// <Grid ap:GridHelper.AutoRowColumn="2,3">
- /// <Button /> // 1,1
- /// <Label /> // 1,2
- /// <TextBox /> // 1,3
- /// <Button /> // 2,1
- /// <Label Grid.ColumnSpan="2" /> // 2,2-3
- /// </Grid>
- /// </Window>
- /// ]]>
- ///
- /// </example>
- public static readonly DependencyProperty AutoRowColumnProperty = DependencyProperty.RegisterAttached(
- "AutoRowColumn",
- typeof(string),
- typeof(GridAssist),
- new FrameworkPropertyMetadata("", FrameworkPropertyMetadataOptions.AffectsMeasure, OnAutoRowColumnChanged)
- );
- private static void OnAutoRowColumnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (!(d is Grid grid))
- return;
- var value = e.NewValue as string;
- if (string.IsNullOrEmpty(value))
- {
- grid.RowDefinitions.Clear();
- grid.ColumnDefinitions.Clear();
- grid.Loaded -= OnGridLoaded;
- return;
- }
- grid.Loaded += OnGridLoaded;
- if (grid.IsLoaded)
- OnGridLoaded(grid, null);
- }
- private static void OnGridLoaded(object sender, RoutedEventArgs e)
- {
- var grid = sender as Grid;
- // 列宽,默认为 Star,即平均分布
- var width = new GridLength(1.0, GridUnitType.Star);
- var split = GridAssist.GetAutoRowColumn(grid).Split(',');
- var r = split[0] != "_" ? int.Parse(split[0]) : 1;
- var c = int.Parse(split[1]);
- // 如果有第三个参数且值为 auto,则宽度为 Auto
- if (split.Length == 3 && split[2].Equals("auto", StringComparison.OrdinalIgnoreCase))
- width = GridLength.Auto;
- grid.RowDefinitions.Clear();
- grid.ColumnDefinitions.Clear();
- for (int i = 0; i < r; i++)
- grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
- for (int i = 0; i < c; i++)
- grid.ColumnDefinitions.Add(new ColumnDefinition { Width = width });
- var cols = grid.ColumnDefinitions.Count;
- var map = new List<bool[]>();
- int x = 0,
- y = 0;
- foreach (UIElement item in grid.Children)
- {
- var rowSpan = Grid.GetRowSpan(item);
- var colSpan = Grid.GetColumnSpan(item);
- // 默认从上到下,从左到右,即任何时候控件的下方和右方都是空的
- // 可能会出现中途有一个 RowSpan > 1 导致其左下方的右侧不为空的情况,暂不处理
- // 同时默认当前的 (x, y) 位置是一个可用位置
- // 当前控件占据的格子
- for (int i = 0; i < rowSpan; i++)
- {
- // 如果 RowDefinition 不够用,则自动添加
- if (map.Count <= y + i)
- {
- while (map.Count <= y + i)
- {
- grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
- map.Add(new bool[cols]);
- }
- }
- map[y + i][x] = true;
- }
- for (int i = 0; i < colSpan; i++)
- {
- if (x + i >= cols)
- break;
- map[y][x + i] = true;
- }
- Grid.SetRow(item, y);
- Grid.SetColumn(item, x);
- // 寻找下一个可用的格子
- while (map[y][x])
- {
- x++;
- if (x >= cols)
- {
- x = 0;
- y++;
- if (y >= map.Count)
- {
- grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
- map.Add(new bool[cols]);
- }
- }
- }
- }
- }
- #endregion
- }
复制代码 wpf项目:https://gitee.com/chenshibao/wpfdemo
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |