在包装面板中设置最大行数

我需要配置一个包装面板,我可以在其中设置最大行数或最大列数。

这是非常必要的,我正在使用WPF 4.0。 但是另一天,我是programmin Metro应用程序,我记得它的一个控件有这个属性,但在WPF中没有(直到我知道)。

在WPF 4.0中是否存在这样的控件? 或者我需要创建一个新的?

您可以设置ItemHeightItemWidth属性来设置最大行数和列数……

有关详细信息,请查看此处

这是一个这样的WrapPanel的实现

XAML:

          

结果:

在此处输入图像描述

WrapPanelWithRowsOrColumnsCount.cs 代码

 using System; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; public class WrapPanelWithRowsOrColumnsCount : WrapPanel { public static readonly DependencyProperty RowsOrColumnsCountProperty = DependencyProperty.Register( "RowsOrColumnsCount", typeof(int), typeof(WrapPanelWithRowsOrColumnsCount), new PropertyMetadata(int.MaxValue)); public int RowsOrColumnsCount { get { return (int)GetValue(RowsOrColumnsCountProperty); } set { SetValue(RowsOrColumnsCountProperty, Math.Max(value, 1)); } } protected override Size MeasureOverride(Size availableSize) { if (Children.Count > 0) { Size newAvailableSize; if (Orientation == Orientation.Horizontal) { var suitableWidth = EstimateSuitableRowOrColumnLength(Children.Cast(), true, availableSize, RowsOrColumnsCount); newAvailableSize = double.IsNaN(suitableWidth) || suitableWidth <= 0 ? availableSize : new Size(Math.Min(suitableWidth, availableSize.Width), availableSize.Height); } else { var suitableHeigth = EstimateSuitableRowOrColumnLength(Children.Cast(), false, availableSize, RowsOrColumnsCount); newAvailableSize = double.IsNaN(suitableHeigth) || suitableHeigth <= 0 ? availableSize : new Size(availableSize.Width, Math.Min(suitableHeigth, availableSize.Height)); } return base.MeasureOverride(newAvailableSize); } else { return base.MeasureOverride(availableSize); } } private double EstimateSuitableRowOrColumnLength(IEnumerable elements, bool trueRowsFalseColumns, Size availableSize, int rowsOrColumnsCount) { var elementsList = elements.ToList(); var desiredLengths = elementsList.Select(el => DesiredLength(el, availableSize, trueRowsFalseColumns)).ToList(); var maxLength = desiredLengths.Where(length => !double.IsNaN(length)).Concat(new[] { 0.0 }).Max(); if (maxLength <= 0.0) { return double.NaN; } var desiredLengthsRepaired = desiredLengths.Select(length => double.IsNaN(length) ? maxLength : length).ToList(); var totalDesiredLength = desiredLengthsRepaired.Sum(); var maxCount = Math.Min(rowsOrColumnsCount, elementsList.Count); var suitableRowOrColumnLength = totalDesiredLength / maxCount; double nextLengthIncrement; while (CountRowsOrColumnsNumber(desiredLengthsRepaired, suitableRowOrColumnLength, out nextLengthIncrement) > maxCount) { suitableRowOrColumnLength += nextLengthIncrement; } suitableRowOrColumnLength = Math.Max(suitableRowOrColumnLength, desiredLengthsRepaired.Max()); return suitableRowOrColumnLength; } private int CountRowsOrColumnsNumber(List desiredLengths, double rowOrColumnLengthLimit, out double nextLengthIncrement) { int rowOrColumnCount = 1; double currentCumulativeLength = 0; bool nextNewRowOrColumn = false; var minimalIncrement = double.MaxValue; foreach (var desiredLength in desiredLengths) { if (nextNewRowOrColumn) { rowOrColumnCount++; currentCumulativeLength = 0; nextNewRowOrColumn = false; } if (currentCumulativeLength + desiredLength > rowOrColumnLengthLimit) { minimalIncrement = Math.Min(minimalIncrement, currentCumulativeLength + desiredLength - rowOrColumnLengthLimit); if (currentCumulativeLength == 0) { nextNewRowOrColumn = true; currentCumulativeLength = 0; } else { rowOrColumnCount++; currentCumulativeLength = desiredLength; } } else { currentCumulativeLength += desiredLength; } } nextLengthIncrement = minimalIncrement != double.MaxValue ? minimalIncrement : 1; return rowOrColumnCount; } private double DesiredLength(UIElement el, Size availableSize, bool trueRowsFalseColumns) { el.Measure(availableSize); Size next = el.DesiredSize; var length = trueRowsFalseColumns ? next.Width : next.Height; if (Double.IsInfinity(length) || Double.IsNaN(length)) { return Double.NaN; } else { return length; } } } 

该解决方案的灵感来自此代码项目文章 。

我认为你想要实现的目标是WPF网格是更好的解决方案。 通过设置特定的网格行数,您可以模拟包裹面板的行为,并且它更灵活。

      .... 
		      	

我认为你能用WrapPanel做到这一点的唯一方法是你知道对象的大小(并且它们是一致的),所以你可以相应地设置WrapPanel的高度/宽度。 虽然这很难看。

需要考虑的一件事是:您希望面板对超出最大行数/列数的元素做什么? 或者总是有合适数量的元素? 如果是这种情况,那么你应该真正看看网格。