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>

照抄就行~

相关推荐
FuckPatience10 小时前
WPF 自定义容器控件的布局
wpf
逆境不可逃11 小时前
深入理解 SingleFlight:从单机到分布式的请求合并方案全解析
分布式·wpf
TDengine (老段)12 小时前
TDengine 逻辑计划生成 — 从 AST 到关系代数算子树
大数据·数据库·物联网·wpf·时序数据库·tdengine·涛思数据
小二·2 天前
微服务架构设计与实践
微服务·架构·wpf
暖馒2 天前
WPF-Prism学习入门步骤记录
学习·wpf
baivfhpwxf20232 天前
雷赛(Leadshine)EtherCAT 数字 I/O 模块(如 EMC-E5064-8)的状态指示灯(I/O 状态)说明
c#·wpf
故渊at2 天前
第二板块:Android 四大组件标准化学理 | 第十二篇:四大组件全景总结与系统服务(System Server)架构
android·架构·wpf·四大组件·system service
伶俜663 天前
# [特殊字符] 零基础学 ArkUI 数据持久化(专题三):5 种存储方案深度对比
学习·华为·wpf·harmonyos
IT策士3 天前
Redis 从入门到精通:数据结构String 与键管理
数据结构·redis·wpf
AC赳赳老秦3 天前
技术文章素材收集自动化:用 OpenClaw 自动爬取行业资讯、技术热点、优质文章
运维·开发语言·python·自动化·wpf·deepseek·openclaw