我目前正在尝试创建一个与VariableGridView类似的控件,但不会使用列/行跨度预先计算的项目高度和宽度,内容将控制项目高度。使用Column span确定控件宽度。您可以找到WIP样本here。
我目前唯一的问题是控件的初始加载。当控件在ScrollViewer中并且它的高度超过窗口/父级的高度时,它不会滚动。见下文:
但是,一旦我调整窗口大小,滚动就会按预期正常工作。见下文:
可能很难看到,但是如果你看一下右侧滚动条的较暗部分,你可以看到它在初始载荷时没有正确调整尺寸。
我怀疑我在控件MeasureOverride
方法中犯了一个错误但是我无法看到我做错了什么:
protected override Size MeasureOverride(Size availableSize) {
// Need to use this method LimitUnboundedSize as when within a
// ScrollViewer an infinite height is supplied within the availableSize
var desiredSize = LimitUnboundedSize(availableSize);
UpdateColumnOffsets();
foreach (var child in Children) {
child.Measure(desiredSize);
}
return desiredSize;
}
private Size LimitUnboundedSize(Size input) {
if (Double.IsInfinity(input.Height)) {
var scrollViewer = this.FindAscendant<ScrollViewer>();
var contentHeight = scrollViewer.ViewportHeight.Equals(0)
? Window.Current.Bounds.Height : scrollViewer.ViewportHeight;
input.Height = (contentHeight >= GetMaxOffset ? contentHeight :
GetMaxOffset);
}
return input;
}
在设置控件的大小之前,如何计算项目的高度?
答案 0 :(得分:0)
我能够解决自己的问题。我需要在安排之前弄清楚我的卡片的位置。这样就会计算columnOffsets,我可以将面板的高度从最大列偏移量开始。
我还没有更新github repo,但是这里需要更新的代码才能工作:
protected override Size ArrangeOverride(Size finalSize) {
foreach (var child in Children) {
var resizable = child as IArrangeable;
resizable?.Arrange(pointDictionary.GetValueOrDefault(resizable.Card));
}
return finalSize;
}
private double GetMaxOffset {
get { return columnOffsetY.Max(); }
}
protected override Size MeasureOverride(Size availableSize) {
var desiredSize = availableSize;
UpdateColumnOffsets();
foreach (var child in Children) {
child.Measure(desiredSize);
CreateOffsetCache(child);
}
if (Double.IsPositiveInfinity(desiredSize.Height))
desiredSize.Height = GetMaxOffset;
return desiredSize;
}
private Dictionary<Card, Point> pointDictionary;
private void CreateOffsetCache(UIElement child) {
var arrangeable = child as IArrangeable;
if (arrangeable == null) return;
var card = arrangeable.Card;
var useColumnOffset = columnOffsetY[card.Column] < columnOffsetY[card.Column + card.ColumnSpan - 1]
? columnOffsetY[card.Column + card.ColumnSpan - 1] : columnOffsetY[card.Column];
var point = new Point(columnOffsetX[card.Column], useColumnOffset);
pointDictionary[card] = point;
SetColumnOffsetY(card.Column, card.ColumnSpan, child.DesiredSize.Height);
}