UWP自定义面板大小基于面板儿童安排高度
问题描述:
我目前正在尝试创建一个控制行为类似于一个VariableGridView,而不是项目高度和宽度预先计算与列/行跨度,内容将控制项目高度。用列宽确定控件宽度。你可以找到一个在制品样品here。UWP自定义面板大小基于面板儿童安排高度
我目前唯一的问题是控制的初始负载。当控件位于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;
}
如何计算的高度,是我的项目要占用在设置我的控件的大小之前?
答
我能解决我自己的问题。我需要在安排之前弄清楚我的牌的位置。这样columnOffsets会被计算出来,我可以将面板的高度设置为最大列偏移量。
我还没有更新的GitHub库还,但这里是一个需要更新的这个工作代码:
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);
}
我可以看到差异下载应用程式后。问题似乎是由于您在初始化时设置了某些内容,并且在调整UI大小之后,GetMaxOffset总是比contentheight高得多。当初始化GetMaxOffset为10时,但在此之后它永远不会回到原始状态。为什么不把高度看作无限? –
不幸的是,我不能让高度无限,如果它是无限的,它会崩溃。从[这里]引用(https://docs.microsoft.com/en-us/windows/uwp/layout/boxpanel-example-custom-panel) - “但是,面板本身无法返回无限大小来自MeasureOverride的值;在布局过程中引发异常。“ – jsmyth886