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>

照抄就行~

相关推荐
兰雪簪轩3 小时前
仓颉Actor模型:分布式并发编程的优雅之道
分布式·wpf
Crazy Struggle12 小时前
WPF 如何支撑一个灵活的流程图编辑器?
.net·wpf·流程图
西岭千秋雪_2 天前
Zookeeper实现分布式锁
java·分布式·后端·zookeeper·wpf
beyond谚语2 天前
第三章 布局
wpf
Aevget3 天前
界面控件DevExpress WPF v25.1新版亮点:数据管理功能全新升级
.net·wpf·界面控件·devexpress·ui开发
baivfhpwxf20233 天前
要在 WPF 中实现数据表对应实体的属性与 UI 控件的双向绑定,并支持修改通知和 UI 自动更新
c#·wpf
极客智造3 天前
深入解析 WPF 中的 DataTemplateSelector:动态模板选择的艺术
wpf
极客智造3 天前
WPF 高级 UI 定制:深入解析 VisualStateManager 与 Adorner
wpf
LateFrames4 天前
使用 Winform / WPF / WinUI3 / Electron 实现异型透明窗口
javascript·electron·wpf·winform·winui3
ifeng09185 天前
HarmonyOS实战项目:AI健康助手(影像识别与健康分析)
人工智能·华为·wpf·harmonyos