private ItemsRepeater SetupRepeater(CustomItemsSource dataSource, ElementFactory elementFactory, ref ScrollViewer scrollViewer, VirtualizingLayout layout)
        {
            var repeater = new ItemsRepeater()
            {
                ItemsSource = dataSource,
#if BUILD_WINDOWS
                ItemTemplate = (Windows.UI.Xaml.IElementFactory)elementFactory,
#else
                ItemTemplate = elementFactory,
#endif
                Layout = layout,
                VerticalCacheLength   = 0,
                HorizontalCacheLength = 0
            };

            scrollViewer = new ScrollViewer
            {
                Content = repeater
            };

            Content = new ItemsRepeaterScrollHost()
            {
                Width        = 200,
                Height       = 200,
                ScrollViewer = scrollViewer
            };

            Content.UpdateLayout();
            int realized = VerifyRealizedRange(repeater, dataSource);

            Verify.IsGreaterThan(realized, 0);

            return(repeater);
        }
Esempio n. 2
0
        private ItemsRepeater SetupRepeater(CustomItemsSource dataSource, ElementFactory elementFactory, ref ScrollViewer scrollViewer, VirtualizingLayout layout)
        {
            var repeater = new ItemsRepeater()
            {
                ItemsSource           = dataSource,
                ItemTemplate          = elementFactory,
                Layout                = layout,
                VerticalCacheLength   = 0,
                HorizontalCacheLength = 0
            };

            scrollViewer = new ScrollViewer
            {
                Content = repeater
            };

            Content = new ItemsRepeaterScrollHost()
            {
                Width        = 200,
                Height       = 200,
                ScrollViewer = scrollViewer
            };

            Content.UpdateLayout();
            if (dataSource.Count > 0)
            {
                int realized = VerifyRealizedRange(repeater, dataSource);
                Verify.IsGreaterThan(realized, 0);
            }

            return(repeater);
        }
Esempio n. 3
0
        public void ValidateRepeaterDefaults()
        {
            RunOnUIThread.Execute(() =>
            {
                var repeater = new ItemsRepeater()
                {
                    ItemsSource = Enumerable.Range(0, 10).Select(i => string.Format("Item #{0}", i)),
                };

                Content = new ItemsRepeaterScrollHost()
                {
                    Width        = 400,
                    Height       = 800,
                    ScrollViewer = new ScrollViewer {
                        Content = repeater
                    }
                };

                Content.UpdateLayout();

                for (int i = 0; i < 10; i++)
                {
                    var element = repeater.TryGetElement(i);
                    Verify.IsNotNull(element);
                    Verify.AreEqual(string.Format("Item #{0}", i), ((TextBlock)element).Text);
                    Verify.AreEqual(i, repeater.GetElementIndex(element));
                }

                Verify.IsNull(repeater.TryGetElement(20));
            });
        }
Esempio n. 4
0
        public void ValidateElementToIndexMapping()
        {
            ItemsRepeater repeater = null;

            RunOnUIThread.Execute(() =>
            {
                var elementFactory               = new RecyclingElementFactory();
                elementFactory.RecyclePool       = new RecyclePool();
                elementFactory.Templates["Item"] = (DataTemplate)XamlReader.Load(
                    @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'> 
                          <TextBlock Text='{Binding}' Height='50' />
                      </DataTemplate>");

                repeater = new ItemsRepeater()
                {
                    ItemsSource = Enumerable.Range(0, 10).Select(i => string.Format("Item #{0}", i)),
#if BUILD_WINDOWS
                    ItemTemplate = (Windows.UI.Xaml.IElementFactory)elementFactory,
#else
                    ItemTemplate = elementFactory,
#endif
                    // Default is StackLayout, so do not have to explicitly set.
                    // Layout = new StackLayout(),
                };

                Content = new ItemsRepeaterScrollHost()
                {
                    Width        = 400,
                    Height       = 800,
                    ScrollViewer = new ScrollViewer
                    {
                        Content = repeater
                    }
                };

                Content.UpdateLayout();

                for (int i = 0; i < 10; i++)
                {
                    var element = repeater.TryGetElement(i);
                    Verify.IsNotNull(element);
                    Verify.AreEqual(string.Format("Item #{0}", i), ((TextBlock)element).Text);
                    Verify.AreEqual(i, repeater.GetElementIndex(element));
                }

                Verify.IsNull(repeater.TryGetElement(20));
            });
        }
        private ItemsRepeater SetupRepeater(object dataSource, VirtualizingLayout layout, string itemContent, out ScrollViewer scrollViewer)
        {
            ItemsRepeater repeater = null;
            ScrollViewer  sv       = null;

            RunOnUIThread.Execute(() =>
            {
                var elementFactory               = new RecyclingElementFactory();
                elementFactory.RecyclePool       = new RecyclePool();
                elementFactory.Templates["Item"] = (DataTemplate)XamlReader.Load(
                    @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'> " + itemContent + @"</DataTemplate>");

                repeater = new ItemsRepeater()
                {
                    ItemsSource = dataSource,
#if BUILD_WINDOWS
                    ItemTemplate = (Windows.UI.Xaml.IElementFactory)elementFactory,
#else
                    ItemTemplate = elementFactory,
#endif
                    Layout = layout,
                    HorizontalCacheLength = 0.0,
                    VerticalCacheLength   = 0.0
                };

                sv = new ScrollViewer
                {
                    Content = repeater
                };

                Content = new ItemsRepeaterScrollHost()
                {
                    Width        = 200,
                    Height       = 200,
                    ScrollViewer = sv
                };
            });

            IdleSynchronizer.Wait();
            scrollViewer = sv;
            return(repeater);
        }
Esempio n. 6
0
        public void VerifyCorrectionsInNonScrollableDirection()
        {
            ItemsRepeater           rootRepeater = null;
            ScrollViewer            scrollViewer = null;
            ItemsRepeaterScrollHost scrollhost   = null;
            ManualResetEvent        viewChanged  = new ManualResetEvent(false);

            RunOnUIThread.Execute(() =>
            {
                scrollhost = (ItemsRepeaterScrollHost)XamlReader.Load(
                    @"<controls:ItemsRepeaterScrollHost Width='400' Height='600'
                     xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
                     xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
                     xmlns:controls='using:Microsoft.UI.Xaml.Controls'>
                    <ScrollViewer Width='400' Height='400' x:Name='scrollviewer'>
                        <controls:ItemsRepeater x:Name='repeater'>
                            <DataTemplate>
                                <StackPanel>
                                    <controls:ItemsRepeater ItemsSource='{Binding}'>
                                        <controls:ItemsRepeater.Layout>
                                            <controls:StackLayout Orientation='Horizontal' />
                                        </controls:ItemsRepeater.Layout>
                                    </controls:ItemsRepeater>
                                </StackPanel>
                            </DataTemplate>
                        </controls:ItemsRepeater>
                    </ScrollViewer>
                </controls:ItemsRepeaterScrollHost>");

                rootRepeater              = (ItemsRepeater)scrollhost.FindName("repeater");
                scrollViewer              = (ScrollViewer)scrollhost.FindName("scrollviewer");
                scrollViewer.ViewChanged += (sender, args) =>
                {
                    if (!args.IsIntermediate)
                    {
                        viewChanged.Set();
                    }
                };

                List <List <int> > items = new List <List <int> >();
                for (int i = 0; i < 100; i++)
                {
                    items.Add(Enumerable.Range(0, 4).ToList());
                }
                rootRepeater.ItemsSource = items;
                Content = scrollhost;
            });

            // scroll down several times and validate no crash
            for (int i = 1; i < 5; i++)
            {
                IdleSynchronizer.Wait();
                RunOnUIThread.Execute(() =>
                {
                    scrollViewer.ChangeView(null, i * 200, null);
                });

                Verify.IsTrue(viewChanged.WaitOne(DefaultWaitTimeInMS));
                viewChanged.Reset();
            }
        }
Esempio n. 7
0
        public void VerifyCurrentAnchor()
        {
            ItemsRepeater           rootRepeater = null;
            ScrollViewer            scrollViewer = null;
            ItemsRepeaterScrollHost scrollhost   = null;
            ManualResetEvent        viewChanged  = new ManualResetEvent(false);

            RunOnUIThread.Execute(() =>
            {
                scrollhost = (ItemsRepeaterScrollHost)XamlReader.Load(
                    @"<controls:ItemsRepeaterScrollHost Width='400' Height='600'
                     xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
                     xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
                     xmlns:controls='using:Microsoft.UI.Xaml.Controls'>
                    <controls:ItemsRepeaterScrollHost.Resources>
                        <DataTemplate x:Key='ItemTemplate' >
                            <TextBlock Text='{Binding}' Height='50'/>
                        </DataTemplate>
                    </controls:ItemsRepeaterScrollHost.Resources>
                    <ScrollViewer x:Name='scrollviewer'>
                        <controls:ItemsRepeater x:Name='rootRepeater' ItemTemplate='{StaticResource ItemTemplate}' VerticalCacheLength='0' />
                    </ScrollViewer>
                </controls:ItemsRepeaterScrollHost>");

                rootRepeater              = (ItemsRepeater)scrollhost.FindName("rootRepeater");
                scrollViewer              = (ScrollViewer)scrollhost.FindName("scrollviewer");
                scrollViewer.ViewChanged += (sender, args) =>
                {
                    if (!args.IsIntermediate)
                    {
                        viewChanged.Set();
                    }
                };

                rootRepeater.ItemsSource = Enumerable.Range(0, 500);
                Content = scrollhost;
            });

            // scroll down several times and validate current anchor
            for (int i = 1; i < 10; i++)
            {
                IdleSynchronizer.Wait();
                RunOnUIThread.Execute(() =>
                {
                    scrollViewer.ChangeView(null, i * 200, null);
                });

                Verify.IsTrue(viewChanged.WaitOne(DefaultWaitTimeInMS));
                viewChanged.Reset();

                RunOnUIThread.Execute(() =>
                {
                    Verify.AreEqual(i * 200, scrollViewer.VerticalOffset);
                    var anchor = PlatformConfiguration.IsOSVersionLessThan(OSVersion.Redstone5) ?
                                 scrollhost.CurrentAnchor :
                                 scrollViewer.CurrentAnchor;
                    var anchorIndex = rootRepeater.GetElementIndex(anchor);
                    Log.Comment("CurrentAnchor: " + anchorIndex);
                    Verify.AreEqual(i * 4, anchorIndex);
                });
            }
        }
        public void ValidateRecycledElementOwnerAffinity()
        {
            RunOnUIThread.Execute(() =>
            {
                ItemsRepeater repeater1 = null;
                ItemsRepeater repeater2 = null;
                const int numItems      = 10;
                var dataCollection      = new ObservableCollection <int>(Enumerable.Range(0, numItems));
                const string recycleKey = "key";

                var dataSource   = MockItemsSource.CreateDataSource <int>(dataCollection, true);
                var layout       = new StackLayout();
                var recyclePool  = new RecyclePool();
                var itemTemplate = (DataTemplate)XamlReader.Load(
                    @"<DataTemplate  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
                         <TextBlock Text='{Binding}' />
                    </DataTemplate>");

                repeater1 = new ItemsRepeater()
                {
                    ItemsSource = dataSource,
                    Layout      = layout,
#if BUILD_WINDOWS
                    ItemTemplate = (Windows.UI.Xaml.IElementFactory) new RecyclingElementFactoryDerived()
#else
                    ItemTemplate = new RecyclingElementFactoryDerived()
#endif
                    {
                        Templates            = { { "key", itemTemplate } },
                        RecyclePool          = recyclePool,
                        SelectTemplateIdFunc = (object data, UIElement owner) => recycleKey
                    }
                };

                repeater2 = new ItemsRepeater()
                {
                    ItemsSource = dataSource,
                    Layout      = layout,
#if BUILD_WINDOWS
                    ItemTemplate = (Windows.UI.Xaml.IElementFactory) new RecyclingElementFactoryDerived()
#else
                    ItemTemplate = new RecyclingElementFactoryDerived()
#endif
                    {
                        Templates            = { { "key", itemTemplate } },
                        RecyclePool          = recyclePool,
                        SelectTemplateIdFunc = (object data, UIElement owner) => recycleKey
                    }
                };

                var root = new StackPanel();
                root.Children.Add(repeater1);
                root.Children.Add(repeater2);

                Content = new ItemsRepeaterScrollHost()
                {
                    Width        = 400,
                    Height       = 400,
                    ScrollViewer = new ScrollViewer()
                    {
                        Content = root
                    }
                };

                Content.UpdateLayout();
                Verify.AreEqual(numItems, VisualTreeHelper.GetChildrenCount(repeater1));
                Verify.AreEqual(numItems, VisualTreeHelper.GetChildrenCount(repeater2));

                // Throw all the elements into the recycle pool
                dataCollection.Clear();
                Content.UpdateLayout();

                for (int i = 0; i < numItems; i++)
                {
                    var element1 = (FrameworkElement)recyclePool.TryGetElement(recycleKey, repeater1);
                    Verify.AreSame(repeater1, element1.Parent);

                    var element2 = (FrameworkElement)recyclePool.TryGetElement(recycleKey, repeater2);
                    Verify.AreSame(repeater2, element2.Parent);
                }
            });
        }
        public void ValidatePhaseInvokeAndOrdering()
        {
            if (!PlatformConfiguration.IsOsVersionGreaterThan(OSVersion.Redstone2))
            {
                Log.Warning("Skipping: GetAvailableSize API is only available in RS3 and above.");
                return;
            }

            ItemsRepeater    repeater           = null;
            int              numPhases          = 6; // 0 to 5
            ManualResetEvent buildTreeCompleted = new ManualResetEvent(false);

            RunOnUIThread.Execute(() =>
            {
                var itemTemplate = (DataTemplate)XamlReader.Load(
                    @"<DataTemplate  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
                            <Button Width='100' Height='100'/>
                        </DataTemplate>");
                repeater = new ItemsRepeater()
                {
                    ItemsSource = Enumerable.Range(0, 10),
#if BUILD_WINDOWS
                    ItemTemplate = (Windows.UI.Xaml.IElementFactory) new CustomElementFactory(numPhases),
#else
                    ItemTemplate = new CustomElementFactory(numPhases),
#endif
                    Layout = new StackLayout(),
                };

                repeater.ElementPrepared += (sender, args) =>
                {
                    if (args.Index == expectedLastRealizedIndex)
                    {
                        Log.Comment("Item 8 Created!");
                        RepeaterTestHooks.BuildTreeCompleted += (sender1, args1) =>
                        {
                            buildTreeCompleted.Set();
                        };
                    }
                };

                Content = new ItemsRepeaterScrollHost()
                {
                    Width        = 400,
                    Height       = 400,
                    ScrollViewer = new ScrollViewer
                    {
                        Content = repeater
                    }
                };

                // CompositionTarget.Rendering += (sender, args) => { Log.Comment("Rendering"); }; // debugging aid
            });

            if (buildTreeCompleted.WaitOne(TimeSpan.FromMilliseconds(2000)))
            {
                RunOnUIThread.Execute(() =>
                {
                    var calls = ElementPhasingManager.ProcessedCalls;

                    Verify.AreEqual(9, calls.Count);
                    calls[0].RemoveAt(0); // Remove the create we did for first measure.
                    foreach (var index in calls.Keys)
                    {
                        var phases = calls[index];
                        Verify.AreEqual(6, phases.Count);
                        for (int i = 0; i < phases.Count; i++)
                        {
                            Verify.AreEqual(i, phases[i]);
                        }
                    }

                    ElementPhasingManager.ProcessedCalls.Clear();
                });
            }
            else
            {
                Verify.Fail("Failed on waiting on build tree.");
            }
        }
        public void ValidateXBindWithoutPhasing()
        {
            ItemsRepeater    repeater  = null;
            int              numPhases = 1; // Just Phase 0 for x:Bind
            ManualResetEvent ElementLoadedCompleted = new ManualResetEvent(false);

            RunOnUIThread.Execute(() =>
            {
                var itemTemplate = (DataTemplate)XamlReader.Load(
                    @"<DataTemplate  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
                            <Button Width='100' Height='100'/>
                        </DataTemplate>");
                repeater = new ItemsRepeater()
                {
                    ItemsSource = Enumerable.Range(0, 10),
#if BUILD_WINDOWS
                    ItemTemplate = (Windows.UI.Xaml.IElementFactory) new CustomElementFactory(numPhases),
#else
                    ItemTemplate = new CustomElementFactory(numPhases),
#endif
                    Layout = new StackLayout(),
                };

                repeater.ElementPrepared += (sender, args) =>
                {
                    if (args.Index == expectedLastRealizedIndex)
                    {
                        Log.Comment("Item 8 Created!");
                        ElementLoadedCompleted.Set();
                    }
                };

                Content = new ItemsRepeaterScrollHost()
                {
                    Width        = 400,
                    Height       = 400,
                    ScrollViewer = new ScrollViewer
                    {
                        Content = repeater
                    }
                };
            });

            if (ElementLoadedCompleted.WaitOne(TimeSpan.FromMilliseconds(2000)))
            {
                RunOnUIThread.Execute(() =>
                {
                    var calls = ElementPhasingManager.ProcessedCalls;

                    Verify.AreEqual(calls.Count, 9);
                    calls[0].RemoveAt(0); // Remove the create we did for first measure.
                    foreach (var index in calls.Keys)
                    {
                        var phases = calls[index];
                        Verify.AreEqual(1, phases.Count); // Just phase 0
                    }

                    ElementPhasingManager.ProcessedCalls.Clear();
                });
            }
            else
            {
                Verify.Fail("Failed on waiting on build tree.");
            }
        }
        public void ValidateElementAnimator()
        {
            ItemsRepeater          repeater = null;
            ElementAnimatorDerived animator = null;
            var data           = new ObservableCollection <string>(Enumerable.Range(0, 10).Select(i => string.Format("Item #{0}", i)));
            var renderingEvent = new ManualResetEvent(false);

            RunOnUIThread.Execute(() =>
            {
                var elementFactory               = new RecyclingElementFactory();
                elementFactory.RecyclePool       = new RecyclePool();
                elementFactory.Templates["Item"] = (DataTemplate)XamlReader.Load(
                    @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'> 
                          <TextBlock Text='{Binding}' Height='50' />
                      </DataTemplate>");

                CompositionTarget.Rendering += (sender, args) =>
                {
                    renderingEvent.Set();
                };

                repeater = new ItemsRepeater()
                {
                    ItemsSource  = data,
                    ItemTemplate = elementFactory,
                };

                Content = new ItemsRepeaterScrollHost()
                {
                    Width        = 400,
                    Height       = 800,
                    ScrollViewer = new ScrollViewer
                    {
                        Content = repeater
                    }
                };
            });

            IdleSynchronizer.Wait();
            Verify.IsTrue(renderingEvent.WaitOne(), "Waiting for rendering event");

            List <CallInfo> showCalls         = new List <CallInfo>();
            List <CallInfo> hideCalls         = new List <CallInfo>();
            List <CallInfo> boundsChangeCalls = new List <CallInfo>();

            RunOnUIThread.Execute(() =>
            {
                animator = new ElementAnimatorDerived()
                {
                    HasShowAnimationValue         = true,
                    HasHideAnimationValue         = true,
                    HasBoundsChangeAnimationValue = true,
                    StartShowAnimationFunc        = (UIElement element, AnimationContext context) =>
                    {
                        showCalls.Add(new CallInfo(repeater.GetElementIndex(element), context));
                    },

                    StartHideAnimationFunc = (UIElement element, AnimationContext context) =>
                    {
                        hideCalls.Add(new CallInfo(repeater.GetElementIndex(element), context));
                    },

                    StartBoundsChangeAnimationFunc = (UIElement element, AnimationContext context, Rect oldBounds, Rect newBounds) =>
                    {
                        boundsChangeCalls.Add(new CallInfo(repeater.GetElementIndex(element), context, oldBounds, newBounds));
                    }
                };
                repeater.Animator = animator;

                renderingEvent.Reset();
                data.Insert(0, "new item");
                data.RemoveAt(2);
            });

            Verify.IsTrue(renderingEvent.WaitOne(), "Waiting for rendering event");
            IdleSynchronizer.Wait();

            Verify.AreEqual(1, showCalls.Count);
            var call = showCalls[0];

            Verify.AreEqual(0, call.Index);
            Verify.AreEqual(AnimationContext.CollectionChangeAdd, call.Context);

            Verify.AreEqual(1, hideCalls.Count);
            call = hideCalls[0];
            Verify.AreEqual(-1, call.Index); // not in the repeater anymore
            Verify.AreEqual(AnimationContext.CollectionChangeRemove, call.Context);

            Verify.AreEqual(1, boundsChangeCalls.Count);
            call = boundsChangeCalls[0];
            Verify.AreEqual(1, call.Index);
            Verify.AreEqual(AnimationContext.CollectionChangeAdd | AnimationContext.CollectionChangeRemove, call.Context);
            Verify.AreEqual(0, call.OldBounds.Y);
            Verify.AreEqual(50, call.NewBounds.Y);

            showCalls.Clear();
            hideCalls.Clear();
            boundsChangeCalls.Clear();

            // Hookup just for show animations and validate.
            RunOnUIThread.Execute(() =>
            {
                animator.HasShowAnimationValue         = true;
                animator.HasHideAnimationValue         = false;
                animator.HasBoundsChangeAnimationValue = false;

                renderingEvent.Reset();
                data.Insert(0, "new item");
                data.RemoveAt(2);
            });

            Verify.IsTrue(renderingEvent.WaitOne(), "Waiting for rendering event");
            IdleSynchronizer.Wait();

            Verify.AreEqual(1, showCalls.Count);
            call = showCalls[0];
            Verify.AreEqual(0, call.Index);
            Verify.AreEqual(AnimationContext.CollectionChangeAdd, call.Context);

            Verify.AreEqual(0, hideCalls.Count);
            Verify.AreEqual(0, boundsChangeCalls.Count);
        }
Esempio n. 12
0
        public async Task ValidateXBindWithoutPhasing()
        {
            ItemsRepeater repeater  = null;
            int           numPhases = 1;   // Just Phase 0 for x:Bind
            bool          ElementLoadedCompleted = false;

            RunOnUIThread.Execute(() =>
            {
                var itemTemplate = (DataTemplate)XamlReader.Load(
                    @"<DataTemplate  xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
                            <Button Width='100' Height='100'/>
                        </DataTemplate>");
                repeater = new ItemsRepeater()
                {
                    ItemsSource  = Enumerable.Range(0, 10),
                    ItemTemplate = new CustomElementFactory(numPhases),
                    Layout       = new StackLayout(),
                };

                repeater.ElementPrepared += (sender, args) =>
                {
                    if (args.Index == expectedLastRealizedIndex)
                    {
                        Log.Comment("Item 8 Created!");
                        ElementLoadedCompleted = true;
                    }
                };

                Content = new ItemsRepeaterScrollHost()
                {
                    Width        = 400,
                    Height       = 400,
                    ScrollViewer = new ScrollViewer
                    {
                        Content = repeater
                    }
                };
            });

            await TestServices.WindowHelper.WaitFor(() => ElementLoadedCompleted, 2000);

            if (ElementLoadedCompleted)
            {
                RunOnUIThread.Execute(() =>
                {
                    var calls = ElementPhasingManager.ProcessedCalls;

                    Verify.AreEqual(calls.Count, 9);
                    calls[0].RemoveAt(0);                     // Remove the create we did for first measure.
                    foreach (var index in calls.Keys)
                    {
                        var phases = calls[index];
                        Verify.AreEqual(1, phases.Count);                         // Just phase 0
                    }

                    ElementPhasingManager.ProcessedCalls.Clear();
                });
            }
            else
            {
                Verify.Fail("Failed on waiting on build tree.");
            }
        }