WPF自定义布局--瀑布布局
引用
提一下瀑布布局的需求,假设一共3列,当插入一个新元素时,都会自动插入在这3列中最短的那一列
在common文件夹新建LayoutLesson.cs文件
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使用它
引入: 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>
照抄就行~