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
dalong101 天前
WPF:DataGrid样式
wpf
samble3 天前
从零搭建工业控制系统(二十二):线程安全与并发控制
c#·wpf·并发·mvvm·线程安全·工业控制
姜穆澜3 天前
OneID 从 0 到 1 完整生产案例(三)
大数据·wpf
dalong103 天前
WPF:MVVM 示例
大数据·wpf
samble3 天前
从零搭建工业控制系统(二十一):状态管理系统——中心状态对象设计
c#·wpf·mvvm·状态管理·工业控制
mengge.cloud4 天前
存储技术基础小白教程
linux·运维·服务器·wpf·存储
DreamLife☼4 天前
复杂Agent系统架构设计
系统架构·wpf·agent·组件·设计·构架·说明
SamChan904 天前
PDF翻译服务端到端基准测试:4款主流方案的吞吐量、延迟、内存占用对比
服务器·网络·python·ai·pdf·wpf
bugcome_com4 天前
Avalonia 控件模板实战:从 WPF 迁移自定义 Button 样式的完整指南
wpf