I implemented custom Windows.UI.Xaml.Controls.Panel
for custom layout items in ListView
and put it to <ItemsPanelTemplate>
. It's works, but is not possible to scroll.
This answer not applicable because I'm using MVVM data binding.
How to make scrolling work?
My Panel
implementation:
public class StaggeredWrapPanel : Panel
{
#region int ItemWidth Property
public int ItemWidth
{
get { return (int)GetValue(ItemWidthProperty); }
set { SetValue(ItemWidthProperty, value); }
}
public static readonly DependencyProperty ItemWidthProperty = DependencyProperty.Register("ItemWidth", typeof(int), typeof(StaggeredWrapPanel), new PropertyMetadata(300, OnItemWidthPropertyChanged));
private static void OnItemWidthPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
(source as StaggeredWrapPanel).InvalidateMeasure();
}
#endregion
protected override Size MeasureOverride(Size availableSize)
{
foreach (var item in Children)
{
item.Measure(new Size(ItemWidth, double.PositiveInfinity));
}
return base.MeasureOverride(availableSize);
}
protected override Size ArrangeOverride(Size finalSize)
{
int columnsCount = (int)(finalSize.Width / ItemWidth);
double[] columnsOffsetsY = new double[columnsCount];
double[] columnsOffsetsX = new double[columnsCount];
for (int i = 0; i < columnsOffsetsX.Length; i++)
{
columnsOffsetsX[i] = i * ItemWidth;
}
int currentColumn = 0;
foreach (var item in Children)
{
if (currentColumn != 0 && columnsOffsetsY[currentColumn] >= columnsOffsetsY[currentColumn - 1])
if (currentColumn == columnsCount - 1)
currentColumn = 0;
else currentColumn++;
Rect rect = new Rect(new Point(columnsOffsetsX[currentColumn], columnsOffsetsY[currentColumn]), new Size(item.DesiredSize.Width, item.DesiredSize.Height));
columnsOffsetsY[currentColumn] += item.DesiredSize.Height;
item.Arrange(rect);
if (currentColumn == 0)
currentColumn++;
if (currentColumn > columnsCount - 1)
currentColumn = 0;
}
return base.ArrangeOverride(finalSize);
}
}