Files
HandyControl/src/Shared/HandyControl_Shared/Controls/Panel/WaterfallPanel.cs
T
2019-04-05 22:23:19 +08:00

85 lines
3.3 KiB
C#

using System.Linq;
using System.Windows;
using System.Windows.Controls;
using HandyControl.Data;
namespace HandyControl.Controls
{
public class WaterfallPanel : Panel
{
public static readonly DependencyProperty GroupsProperty = DependencyProperty.Register(
"Groups", typeof(int), typeof(WaterfallPanel), new FrameworkPropertyMetadata(ValueBoxes.Int2Box, FrameworkPropertyMetadataOptions.AffectsMeasure), IsGroupsValid);
public int Groups
{
get => (int) GetValue(GroupsProperty);
set => SetValue(GroupsProperty, value);
}
private static bool IsGroupsValid(object value)
{
var v = (int)value;
return v >= 1;
}
public static readonly DependencyProperty OrientationProperty = DependencyProperty.Register(
"Orientation", typeof(Orientation), typeof(WaterfallPanel), new FrameworkPropertyMetadata(
Orientation.Horizontal, FrameworkPropertyMetadataOptions.AffectsMeasure));
public Orientation Orientation
{
get => (Orientation) GetValue(OrientationProperty);
set => SetValue(OrientationProperty, value);
}
protected override Size MeasureOverride(Size constraint)
{
if (Groups < 1) return constraint;
var children = InternalChildren;
Size panelSize;
if (Orientation == Orientation.Horizontal)
{
var heightArr = new double[Groups].ToList();
var itemWidth = constraint.Width / Groups;
if (double.IsNaN(itemWidth) || double.IsInfinity(itemWidth)) return constraint;
for (int i = 0, count = children.Count; i < count; i++)
{
var child = children[i];
if (child == null) continue;
child.Measure(constraint);
var minIndex = heightArr.IndexOf(heightArr.Min());
var minY = heightArr[minIndex];
child.Arrange(new Rect(new Point(minIndex * itemWidth, minY), new Size(itemWidth, child.DesiredSize.Height)));
heightArr[minIndex] = minY + child.DesiredSize.Height;
}
panelSize = new Size(constraint.Width, heightArr.Max());
}
else
{
var widthArr = new double[Groups].ToList();
var itemHeight = constraint.Height / Groups;
if (double.IsNaN(itemHeight) || double.IsInfinity(itemHeight)) return constraint;
for (int i = 0, count = children.Count; i < count; i++)
{
var child = children[i];
if (child == null) continue;
child.Measure(constraint);
var minIndex = widthArr.IndexOf(widthArr.Min());
var minX = widthArr[minIndex];
child.Arrange(new Rect(new Point(minX, minIndex * itemHeight), new Size(child.DesiredSize.Width, itemHeight)));
widthArr[minIndex] = minX + child.DesiredSize.Width;
}
panelSize = new Size(widthArr.Max(), constraint.Height);
}
return panelSize;
}
}
}