UWP自定义面板大小基于面板儿童安排高度

UWP自定义面板大小基于面板儿童安排高度

问题描述:

我目前正在尝试创建一个控制行为类似于一个VariableGridView,而不是项目高度和宽度预先计算与列/行跨度,内容将控制项目高度。用列宽确定控件宽度。你可以找到一个在制品样品hereUWP自定义面板大小基于面板儿童安排高度

我目前唯一的问题是控制的初始负载。当控件位于ScrollViewer中并且它的高度超过了窗口/父级的高度时,它不会滚动。请看下图:

Scrollbar fills the right hand side

然而,一旦我调整窗口的大小,滚动工作正常预期。请看下图:

You can see here the scrollbar has fixed itself and is the right size for the content of the Panel

这可能是很难看到,但如果你看一下在右边的滚动条的较暗的部分,你可以看到它不是初始加载正确尺寸本身。

我怀疑我做的控制错误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

我可以看到差异下载应用程式后。问题似乎是由于您在初始化时设置了某些内容,并且在调整UI大小之后,GetMaxOffset总是比contentheight高得多。当初始化GetMaxOffset为10时,但在此之后它永远不会回到原始状态。为什么不把高度看作无限? –

+0

不幸的是,我不能让高度无限,如果它是无限的,它会崩溃。从[这里]引用(https://docs.microsoft.com/en-us/windows/uwp/layout/boxpanel-example-custom-panel) - “但是,面板本身无法返回无限大小来自MeasureOverride的值;在布局过程中引发异常。“ – jsmyth886

我能解决我自己的问题。我需要在安排之前弄清楚我的牌的位置。这样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); 
}