經過一番研究,以滿足要求最簡單的方法是用在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);
}
}
您可以創建一個自定義'GridView'類(只是從基本'GridView'繼承),它重寫'ArrangeOverride'。在安排物品時,首先測量所有物品(不是每次一個),然後根據最大物品選擇物品尺寸。 –
@Nate Diamond謝謝你,但你能否進一步闡述1-2步?我問的原因是,在調用'ArrangeOverride'期間重新排列項目會導致遞歸佈局更新,幾乎有保證的異常。除此之外,如果我朝這個方向發展,定製'ItemsPanel'容器而不是'GridView'也許會有意義。 –
我不一定要重新安排它們。 ArrangeOverride應該調用每個子項目的安排,傳遞項目將要提供的空間量。因此,這意味着它應該能夠搜索項目的「度量」值(而不是僅使用第一項)並查找其中最大的值。確實,這可以用'Panel'來完成,比如製作一個自定義的'VariableSizeWrapGrid'。 –