我试图在GridView
中显示多个项目。它的选择主要是因为它的水平滚动行为。
看起来GridView
根据第一个项目维度定义项目大小。在下面的代码示例中,如果年份从1月份开始,则会裁剪较长的月份名称,但如果第一个项目较宽,则会按预期显示名称。
我确实希望GridView
保持所有宽度相同的项目,但必须是最大项目的宽度。高度相同,但在我的情况下,高度是恒定的。
使用GridView
是否有相对简单的方法来实现这一目标,或者可能有更合适的控件?
<GridView>
<GridView.Items>
<x:String>January</x:String>
<x:String>February</x:String>
<x:String>...</x:String>
<x:String>September</x:String>
<x:String>October</x:String>
<x:String>November</x:String>
<x:String>December</x:String>
</GridView.Items>
</GridView>
N.B。那里有不同/可变项目大小的多个示例。不幸的是,不需要什么。
答案 0 :(得分:0)
经过一些研究,满足要求的最简单方法是使用ItemsPanelTemplate
中的自定义面板。
一些被拒绝的方法是
1)扩展GridView
:当开发人员从GridView派生时可以访问大量有趣的信息时,实际的布局管理在GridView.ItemsPanel
控件中执行,修改项目位置以外的位置需要一些黑客或脆弱的设计决定
2)扩展现有的ItemPanel
容器:这是最自然的方法,但由于WrapGrid
或VariableSizedWrapGrid
等类是密封的,因此无法实现。
以下是使用GridView
的自定义面板的示例
如果整个GridView
中的项目太少,则对齐设置会在左上角而不是中心定位项目。
保证金补偿滚动条的默认行为以重叠内容。
<GridView ... >
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<controls:GridViewPanel
HorizontalAlignment="Left"
VerticalAlignment="Top"
Margin="0,0,0,24" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
...
</GridView>
完整的自定义面板代码如下。它有意简化,但可以轻松扩展以满足特定的附加要求,例如更精确的布局控制,可变列宽,虚拟化等。虽然使用更高级GridView
功能(如分组),但尚未对其进行测试。
using System;
using Windows.Foundation;
using Windows.UI.Xaml.Controls;
/// <summary>
/// Uniformly positions child items in columns to present in WrapGrid.
/// Uses largest item's DesiredSize for item size mesasurements.
/// Expects limited height and unbound width.
/// </summary>
public class GridViewPanel : Panel
{
protected override Size MeasureOverride(Size availableSize)
{
return ArrangeInternal(availableSize, callArrange: false);
}
protected override Size ArrangeOverride(Size finalSize)
{
return ArrangeInternal(finalSize);
}
private Size ArrangeInternal(Size size, bool callArrange = true)
{
// measure max desired item size
//
double itemWidth = 0.0, itemHeight = 0.0;
foreach (var item in Children)
{
item.Measure(size);
itemWidth = Math.Max(itemWidth, item.DesiredSize.Width);
itemHeight = Math.Max(itemHeight, item.DesiredSize.Height);
}
// requested item height can't exceed total available height
itemHeight = Math.Min(itemHeight, size.Height);
// position each child and get total content size
//
double totalWidth = 0.0, totalHeight = 0.0;
double x = 0.0, y = 0.0;
foreach (var item in Children)
{
if (y + itemHeight > size.Height)
{
// if item won't fit, move to the next column
totalHeight = Math.Max(totalHeight, y);
y = 0;
x += itemWidth;
}
// implicitly, item fits in current column
if (callArrange) item.Arrange(new Rect(x, y, itemWidth, itemHeight));
y += itemHeight;
}
totalWidth = x + itemWidth;
totalHeight = Math.Max(totalHeight, y);
return new Size(totalWidth, totalHeight);
}
}