Пример #1
0
        // [TestMethod] Temporarily disabled for bug 18866003
        public void ValidateItemsRepeaterScrollHostScenario()
        {
            var realizationRects = new List <Rect>();
            var scrollViewer     = (ScrollViewer)null;
            var viewChangedEvent = new ManualResetEvent(false);
            int waitTime         = 2000; // 2 seconds

            RunOnUIThread.Execute(() =>
            {
                var repeater = new ItemsRepeater()
                {
                    Layout = GetMonitoringLayout(new Size(500, 600), realizationRects),
                    HorizontalCacheLength = 0.0,
                    VerticalCacheLength   = 0.0
                };

                scrollViewer = new ScrollViewer
                {
                    Content = repeater,
                    HorizontalScrollBarVisibility = ScrollBarVisibility.Hidden,
                    VerticalScrollBarVisibility   = ScrollBarVisibility.Hidden,
                };

                scrollViewer.ViewChanged += (sender, args) =>
                {
                    if (!args.IsIntermediate)
                    {
                        viewChangedEvent.Set();
                    }
                };

                var tracker = new ItemsRepeaterScrollHost()
                {
                    Width        = 200,
                    Height       = 300,
                    ScrollViewer = scrollViewer
                };

                Content = tracker;
                Content.UpdateLayout();

                // First layout pass will invalidate measure during the first arrange
                // so that we can get a viewport during the second measure/arrange pass.
                // That's why Measure gets invoked twice.
                // After that, ScrollViewer.SizeChanged is raised and it also invalidates
                // layout (third pass).
                Verify.AreEqual(3, realizationRects.Count);
                Verify.AreEqual(new Rect(0, 0, 0, 0), realizationRects[0]);
                Verify.AreEqual(new Rect(0, 0, 200, 300), realizationRects[1]);
                Verify.AreEqual(new Rect(0, 0, 200, 300), realizationRects[2]);
                realizationRects.Clear();

                viewChangedEvent.Reset();
                scrollViewer.ChangeView(null, 100.0, 1.0f, disableAnimation: true);
            });

            Verify.IsTrue(viewChangedEvent.WaitOne(waitTime), "Waiting for view changed");
            IdleSynchronizer.Wait();

            RunOnUIThread.Execute(() =>
            {
                Verify.AreEqual(new Rect(0, 100, 200, 300), realizationRects.Last());
                realizationRects.Clear();

                viewChangedEvent.Reset();
                // Max viewport offset is (300, 400). Horizontal viewport offset
                // is expected to get coerced from 400 to 300.
                scrollViewer.ChangeView(400, 100.0, 1.0f, disableAnimation: true);
            });

            Verify.IsTrue(viewChangedEvent.WaitOne(waitTime), "Waiting for view changed");
            IdleSynchronizer.Wait();

            RunOnUIThread.Execute(() =>
            {
                Verify.AreEqual(new Rect(300, 100, 200, 300), realizationRects.Last());
                realizationRects.Clear();

                viewChangedEvent.Reset();
                scrollViewer.ChangeView(null, null, 2.0f, disableAnimation: true);
            });

            Verify.IsTrue(viewChangedEvent.WaitOne(waitTime), "Waiting for view changed");
            IdleSynchronizer.Wait();

            RunOnUIThread.Execute(() =>
            {
                Verify.AreEqual(new Rect(300, 100, 100, 150), realizationRects.Last());
                realizationRects.Clear();
            });
        }
Пример #2
0
        public void BringIntoViewOfExistingItemsDoesNotChangeScrollOffset()
        {
            System.Windows.Controls.ScrollViewerEx scrollViewer = null;
            ItemsRepeater  repeater = null;
            AutoResetEvent scrollViewerScrolledEvent = new AutoResetEvent(false);

            RunOnUIThread.Execute(() =>
            {
                repeater             = new ItemsRepeater();
                repeater.ItemsSource = Enumerable.Range(0, 100).Select(x => x.ToString()).ToList();

                scrollViewer = new System.Windows.Controls.ScrollViewerEx()
                {
                    Content   = repeater,
                    MaxHeight = 400,
                    MaxWidth  = 200
                };


                Content = scrollViewer;
                Content.UpdateLayout();
            });

            IdleSynchronizer.Wait();

            RunOnUIThread.Execute(() =>
            {
                Log.Comment("Scroll to end");
                scrollViewer.ViewChanged += (object sender, ScrollViewerViewChangedEventArgs e) =>
                {
                    if (!e.IsIntermediate)
                    {
                        Log.Comment("ScrollViewer scrolling finished");
                        scrollViewerScrolledEvent.Set();
                    }
                };
                scrollViewer.ChangeView(null, repeater.ActualHeight, null);
                scrollViewer.UpdateLayout();
            });

            Log.Comment("Wait for scrolling");
            if (Debugger.IsAttached)
            {
                scrollViewerScrolledEvent.WaitOne();
            }
            else
            {
                if (!scrollViewerScrolledEvent.WaitOne(TimeSpan.FromMilliseconds(5000)))
                {
                    throw new Exception("Timeout expiration in WaitForEvent.");
                }
            }

            IdleSynchronizer.Wait();

            double endOfScrollOffset = 0;

            RunOnUIThread.Execute(() =>
            {
                Log.Comment("Determine scrolled offset");
                endOfScrollOffset = scrollViewer.VerticalOffset;
                // Idea: we might not have scrolled to the end, however we should at least have moved so much that the end is not too far away
                Verify.IsTrue(Math.Abs(endOfScrollOffset - repeater.ActualHeight) < 500, $"We should at least have scrolled some amount. " +
                              $"ScrollOffset:{endOfScrollOffset} Repeater height: {repeater.ActualHeight}");

                var lastItem = (FrameworkElement)repeater.GetOrCreateElement(99);
                lastItem.UpdateLayout();
                Log.Comment("Bring last element into view");
                lastItem.BringIntoView();
            });

            IdleSynchronizer.Wait();

            RunOnUIThread.Execute(() =>
            {
                Log.Comment("Verify position did not change");
                Verify.IsTrue(Math.Abs(endOfScrollOffset - scrollViewer.VerticalOffset) < 1);
            });
        }