Let’s say we have a GridView in Windows Store. We want the items arrange according to this:
- Single column
- No overflow / scrolling
- Excess items should not be displayed (and no half displayed items on the bottom edge of the screen)
For some reason there is a no built-in panel that will do this. So I rolled my own. You can see the implementation below:
public class SingleColumnUnscrollablePanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
var requiredHeight = 0.0;
var remainingHeight = availableSize.Height;
var largestDesiredWidth = 0.0;
foreach (FrameworkElement child in Children)
{
child.Measure(new Size(availableSize.Width, availableSize.Height));
var desiredHeight = child.DesiredSize.Height;
var desiredWidth = child.DesiredSize.Width;
if (remainingHeight >= desiredHeight)
{
largestDesiredWidth = Math.Max(largestDesiredWidth, desiredWidth);
remainingHeight -= desiredHeight;
requiredHeight += desiredHeight;
}
}
return new Size(largestDesiredWidth, requiredHeight);
}
protected override Size ArrangeOverride(Size finalSize)
{
var availableHeight = finalSize.Height;
var currentHeight = 0.0;
var mychildren = Children;
if (!mychildren.Any())
return finalSize;
var largestDesiredWidth = mychildren.Max(s => s.DesiredSize.Width);
foreach (var child in mychildren)
{
var desiredHeight = child.DesiredSize.Height;
var desiredWidth = child.DesiredSize.Width;
if (desiredHeight + currentHeight > availableHeight)
break;
child.Arrange(new Rect(0, currentHeight, desiredWidth, desiredHeight)); //largestDesiredWidth, desiredHeight));
currentHeight += desiredHeight;
}
return new Size(largestDesiredWidth, currentHeight);
}
}
Using it in a GridView:
<GridView.ItemsPanel> <ItemsPanelTemplate> <controls:SingleColumnUnscrollablePanel /> </ItemsPanelTemplate> </GridView.ItemsPanel>