农民 发表于 2024-12-30 21:17:04

DataGrid的主动行列表现

新建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 != "_" ? int.Parse(split) : 1;
                                var c = int.Parse(split);
                                // 如果有第三个参数且值为 auto,则宽度为 Auto
                                if (split.Length == 3 && split.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);
                                                        }
                                                }

                                                map = true;
                                        }

                                        for (int i = 0; i < colSpan; i++)
                                        {
                                                if (x + i >= cols)
                                                        break;
                                                map = true;
                                        }

                                        Grid.SetRow(item, y);
                                        Grid.SetColumn(item, x);

                                        // 寻找下一个可用的格子
                                        while (map)
                                        {
                                                x++;
                                                if (x >= cols)
                                                {
                                                        x = 0;
                                                        y++;
                                                        if (y >= map.Count)
                                                        {
                                                                grid.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto });
                                                                map.Add(new bool);
                                                        }
                                                }
                                        }
                                }
                        }

                        #endregion
                }wpf项目:https://gitee.com/chenshibao/wpfdemo

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: DataGrid的主动行列表现