WPF自定义布局--瀑布布局

引用

提一下瀑布布局的需求,假设一共3列,当插入一个新元素时,都会自动插入在这3列中最短的那一列

在common文件夹新建LayoutLesson.cs文件

csharp 复制代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace Machine.Common //这里需要成自己的实际项目名
{
    /// <summary>
    /// 瀑布布局
    /// </summary>
    public class XHPanel : Panel
    {
        // 空隙
        private double _rowSpace = 0;

        public double RowSpace
        {
            get { return _rowSpace; }
            set
            {
                _rowSpace = value;
                // 自动刷新UI
                this.InvalidateVisual();
            }
        }

        private double _columnSpace = 0;

        public double ColumnSpace
        {
            get { return _columnSpace; }
            set
            {
                _columnSpace = value;
                // 重新布局
                this.InvalidateVisual();
            }
        }


        // 测量
        protected override Size MeasureOverride(Size availableSize)
        {
            double total_y = 0; // 累计高度
            // 遍历所有的子项
            double per_width = (availableSize.Width - ColumnSpace * 2) / 3;
            foreach (UIElement item in this.InternalChildren)
            {
                item.Measure(new Size(per_width, availableSize.Height));
                total_y += item.DesiredSize.Height;
            }
            return new Size(availableSize.Width, total_y);
        }
        // 排列
        protected override Size ArrangeOverride(Size finalSize)
        {
            double offset_y = 0, offset_x = 0;
            double per_width = (finalSize.Width - ColumnSpace * 2) / 3;
            double maxHeight = 0;
            List<Test> testList = new List<Test>();
            for (int i = 0; i < this.InternalChildren.Count; i++)
            {
                UIElement item = this.InternalChildren[i];
                if (i == 0)
                {
                    item.Arrange(new Rect(offset_x, (offset_y + RowSpace), per_width, item.DesiredSize.Height));
                    testList.Add(new Test { ValueX = 0, TotalColumn = item.DesiredSize.Height });
                }
                else if (i == 1)
                {
                    item.Arrange(new Rect(per_width, (offset_y + RowSpace), per_width, item.DesiredSize.Height));
                    testList.Add(new Test { ValueX = per_width, TotalColumn = item.DesiredSize.Height });
                }
                else if (i == 2)
                {
                    item.Arrange(new Rect(per_width * 2, (offset_y + RowSpace), per_width, item.DesiredSize.Height));
                    testList.Add(new Test { ValueX = per_width * 2, TotalColumn = item.DesiredSize.Height });
                }
                else
                {
                    double minC = 10000;
                    foreach (var m in testList)
                    {
                        minC = Math.Min(minC, m.TotalColumn);
                    }
                    Test test = new Test() { TotalColumn = minC };
                    testList.ForEach(f =>
                    {
                        if (test.TotalColumn == f.TotalColumn)
                        {
                            test.ValueX = f.ValueX;
                        }
                    });
                    item.Arrange(new Rect(test.ValueX, test.TotalColumn, per_width, item.DesiredSize.Height));
                    testList.ForEach(f => {
                        if (f.ValueX == test.ValueX)
                        {
                            f.TotalColumn += item.DesiredSize.Height;
                        }
                    });
                }
            }
            return base.ArrangeOverride(finalSize);
        }
    }
    class Test
    {
        public double ValueX { get; set; } // X坐标
        public double TotalColumn { get; set; } // 列总高度
    }
}

xaml使用它

xml 复制代码
引入: xmlns:lang="clr-namespace:Machine.Common"

 <lang:XHPanel ColumnSpace="2" RowSpace="2">
     <GroupBox Header="结果数据1">
         <StackPanel>
             <WrapPanel Margin="5" HorizontalAlignment="Left">
                 <Label Content="X:坐标(绝对)" Foreground="#01c2ff"/>
             </WrapPanel>
             <WrapPanel Margin="5" HorizontalAlignment="Left">
                 <Label Content="X:坐标(绝对)" Foreground="#01c2ff"/>
             </WrapPanel>
         </StackPanel>
     </GroupBox> 
     <GroupBox Header="结果数据2">
         <StackPanel>
             <WrapPanel Margin="5" HorizontalAlignment="Left">
                 <Label Content="X:坐标(绝对)" Foreground="#01c2ff"/>
             </WrapPanel>
         </StackPanel>
     </GroupBox>
</lang:XHPanel>

照抄就行~

相关推荐
xcLeigh1 天前
WPF基础 | WPF 基础概念全解析:布局、控件与事件
c#·wpf
xcLeigh2 天前
WPF基础 | 初探 WPF:理解其核心架构与开发环境搭建
架构·c#·wpf
源之缘-OFD先行者2 天前
WPF常见面试题解答
wpf
星江月2 天前
关于WPF中ComboBox文本查询功能
wpf·mvvm·查找·combobox·路由事件
MasterNeverDown2 天前
WPF 打印功能实现
wpf
code_shenbing2 天前
基于 WPF 平台使用纯 C# 制作流体动画
开发语言·c#·wpf
code_shenbing2 天前
基于 WPF 平台实现成语游戏
游戏·c#·wpf
玉面小君3 天前
探索WPF中的RelativeSource:灵活的资源绑定利器
wpf
军训猫猫头3 天前
56.命令绑定 C#例子 WPF例子
开发语言·c#·wpf