未验证 提交 4dda72bb 编写于 作者: A Ashish Kumar Singh 提交者: GitHub

fix hang when margin is not a multiple of DPI rounding quantum (#5841) (#6004)

Co-authored-by: NSam Bent <sambent@microsoft.com>
上级 9e130d78
......@@ -3079,6 +3079,38 @@ private bool IsOnCurrentPage(FrameworkElement viewPort, FrameworkElement element
return ElementViewportPosition.None;
}
// this version also returns the element's layout rectangle (in viewport's coordinates).
// VirtualizingStackPanel needs this, to determine the element's scroll offset.
internal static ElementViewportPosition GetElementViewportPosition(FrameworkElement viewPort,
UIElement element,
FocusNavigationDirection axis,
bool fullyVisible,
bool ignorePerpendicularAxis,
out Rect elementRect,
out Rect layoutRect)
{
ElementViewportPosition position = GetElementViewportPosition(
viewPort,
element,
axis,
fullyVisible,
false,
out elementRect);
if (position == ElementViewportPosition.None)
{
layoutRect = Rect.Empty;
}
else
{
Visual parent = VisualTreeHelper.GetParent(element) as Visual;
Debug.Assert(element != viewPort && element.IsArrangeValid && parent != null, "GetElementViewportPosition called in unsupported situation");
layoutRect = CorrectCatastrophicCancellation(parent.TransformToAncestor(viewPort)).TransformBounds(element.PreviousArrangeRect);
}
return position;
}
// in large virtualized hierarchical lists (TreeView or grouping), the transform
// returned by element.TransformToAncestor(viewport) is vulnerable to catastrophic
// cancellation. If element is at the top of the viewport, but embedded in
......
......@@ -1189,6 +1189,7 @@ private void ClearAnchorInformation(bool shouldAbort)
if (fe.IsVisible)
{
Rect elementRect;
Rect layoutRect;
// get the vp-position of the element, ignoring the secondary axis
// (DevDiv2 1136036, 1203626 show two different cases why we
......@@ -1201,7 +1202,8 @@ private void ClearAnchorInformation(bool shouldAbort)
direction,
false /*fullyVisible*/,
!isVSP45Compat /*ignorePerpendicularAxis*/,
out elementRect);
out elementRect,
out layoutRect);
if (elementPosition == ElementViewportPosition.PartiallyInViewport ||
elementPosition == ElementViewportPosition.CompletelyInViewport)
......@@ -1287,20 +1289,35 @@ private void ClearAnchorInformation(bool shouldAbort)
{
if (direction == FocusNavigationDirection.Down)
{
firstContainerOffsetFromViewport = elementRect.Y;
if (!isVSP45Compat)
{
firstContainerOffsetFromViewport -= fe.Margin.Top;
}
}
if (isVSP45Compat)
{
firstContainerOffsetFromViewport = elementRect.Y;
}
else
{
// include the leading margin in the offset. Simply subtracting
// the margin doesn't work when layout rounding is in effect, as
// we can't deduce how rounding affected the arrangement of the
// element and its margin. Instead, just use the layout rect directly.
firstContainerOffsetFromViewport = layoutRect.Top;
}
}
else // (direction == FocusNavigationDirection.Right)
{
firstContainerOffsetFromViewport = elementRect.X;
if (!isVSP45Compat)
{
firstContainerOffsetFromViewport -= fe.Margin.Left;
}
}
if (isVSP45Compat)
{
firstContainerOffsetFromViewport = elementRect.X;
}
else
{
// include the leading margin in the offset. Simply subtracting
// the margin doesn't work when layout rounding is in effect, as
// we can't deduce how rounding affected the arrangement of the
// element and its margin. Instead, just use the layout rect directly.
firstContainerOffsetFromViewport = layoutRect.Left;
}
}
}
else if (findTopContainer && isTopContainer)
{
......@@ -1931,7 +1948,7 @@ public ScrollViewer ScrollOwner
}
set
{
if (_scrollData == null) EnsureScrollData();
EnsureScrollData();
if (value != _scrollData._scrollOwner)
{
ResetScrolling(this);
......@@ -9510,10 +9527,6 @@ private int ItemCount
private void EnsureScrollData()
{
if (_scrollData == null) { _scrollData = new ScrollData(); }
else
{
Debug.Assert(_scrollData._scrollOwner != null, "Scrolling an unconnected VSP");
}
}
private static void ResetScrolling(VirtualizingStackPanel element)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册