public void When_UpdateLayout_Then_TreeNotMeasuredUsingCachedValue() { if (Window.Current.RootElement is Panel root) { var sut = new Grid { HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch }; var originalRootAvailableSize = LayoutInformation.GetAvailableSize(root); var originalRootDesiredSize = LayoutInformation.GetDesiredSize(root); var originalRootLayoutSlot = LayoutInformation.GetLayoutSlot(root); Size availableSize; Rect layoutSlot; try { LayoutInformation.SetAvailableSize(root, default); LayoutInformation.SetDesiredSize(root, default); LayoutInformation.SetLayoutSlot(root, default); root.Children.Add(sut); sut.UpdateLayout(); availableSize = LayoutInformation.GetAvailableSize(sut); layoutSlot = LayoutInformation.GetLayoutSlot(sut); } finally { LayoutInformation.SetAvailableSize(root, originalRootAvailableSize); LayoutInformation.SetDesiredSize(root, originalRootDesiredSize); LayoutInformation.SetLayoutSlot(root, originalRootLayoutSlot); root.Children.Remove(sut); try { root.UpdateLayout(); } catch { } // Make sure to restore visual tree if test has failed! } Assert.AreNotEqual(default, availableSize);
void DoPhasedWorkCallback() { MarkCallbackRecieved(); if (m_pendingElements.Count > 0 && !BuildTreeScheduler.ShouldYield()) { var visibleWindow = m_owner.VisibleWindow; SortElements(visibleWindow); int currentIndex = m_pendingElements.Count - 1; do { var info = m_pendingElements[currentIndex]; var element = info.Element; var virtInfo = info.VirtInfo; var dataIndex = virtInfo.Index; int currentPhase = virtInfo.Phase; if (currentPhase > 0) { int nextPhase = VirtualizationInfo.PhaseReachedEnd; virtInfo.DataTemplateComponent.ProcessBindings(virtInfo.Data, -1 /* item index unused */, currentPhase, out nextPhase); ValidatePhaseOrdering(currentPhase, nextPhase); var previousAvailableSize = LayoutInformation.GetAvailableSize(element); element.Measure(previousAvailableSize); if (nextPhase > 0) { virtInfo.Phase = nextPhase; // If we are the first item or // If the current items phase is higher than the next items phase, then move to the next item. if (currentIndex == 0 || virtInfo.Phase > m_pendingElements[currentIndex - 1].VirtInfo.Phase) { currentIndex--; } } else { m_pendingElements.RemoveAt(currentIndex); currentIndex--; } } else { throw new InvalidOperationException("Cleared element found in pending list which is not expected"); } var pendingCount = (int)(m_pendingElements.Count); if (currentIndex == -1) { // Reached the top, start from the bottom again currentIndex = pendingCount - 1; } else if (currentIndex > -1 && currentIndex < pendingCount - 1) { // If the next element is oustide the visible window and there are elements in the visible window // go back to the visible window. bool nextItemIsVisible = SharedHelpers.DoRectsIntersect(visibleWindow, m_pendingElements[currentIndex].VirtInfo.ArrangeBounds); if (!nextItemIsVisible) { bool haveVisibleItems = SharedHelpers.DoRectsIntersect(visibleWindow, m_pendingElements[pendingCount - 1].VirtInfo.ArrangeBounds); if (haveVisibleItems) { currentIndex = pendingCount - 1; } } } } while (m_pendingElements.Count > 0 && !BuildTreeScheduler.ShouldYield()); } if (m_pendingElements.Count > 0) { RegisterForCallback(); } }