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)); }); }
public void ValidateMappingAndAutoRecycling() { ItemsRepeater repeater = null; ScrollViewer scrollViewer = null; RunOnUIThread.Execute(() => { var layout = new MockVirtualizingLayout() { MeasureLayoutFunc = (availableSize, context) => { var element0 = context.GetOrCreateElementAt(index: 0); // lookup - repeater will give back the same element and note that this element will not // be pinned - i.e it will be auto recycled after a measure pass where GetElementAt(0) is not called. var element0lookup = context.GetOrCreateElementAt(index: 0, options: ElementRealizationOptions.None); var element1 = context.GetOrCreateElementAt(index: 1, options: ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle); // forcing a new element for index 1 that will be pinned (not auto recycled). This will be // a completely new element. Repeater does not do the mapping/lookup when forceCreate is true. var element1Clone = context.GetOrCreateElementAt(index: 1, options: ElementRealizationOptions.ForceCreate | ElementRealizationOptions.SuppressAutoRecycle); Verify.AreSame(element0, element0lookup); Verify.AreNotSame(element1, element1Clone); element0.Measure(availableSize); element1.Measure(availableSize); element1Clone.Measure(availableSize); return(new Size(100, 100)); }, }; Content = CreateAndInitializeRepeater( itemsSource: Enumerable.Range(0, 5), layout: layout, elementFactory: GetDataTemplate("<Button>Hello</Button>"), repeater: ref repeater, scrollViewer: ref scrollViewer); Content.UpdateLayout(); Verify.IsNotNull(repeater.TryGetElement(0)); Verify.IsNotNull(repeater.TryGetElement(1)); layout.MeasureLayoutFunc = null; repeater.InvalidateMeasure(); Content.UpdateLayout(); Verify.IsNull(repeater.TryGetElement(0)); // not pinned, should be auto recycled. Verify.IsNotNull(repeater.TryGetElement(1)); // pinned, should stay alive }); }
public void ValidateStackLayoutDisabledVirtualizationWithItemsRepeater() { RunOnUIThread.Execute(() => { var repeater = new ItemsRepeater(); var stackLayout = new StackLayout(); stackLayout.DisableVirtualization = true; repeater.Layout = stackLayout; repeater.ItemsSource = Enumerable.Range(0, 10); repeater.ItemTemplate = (DataTemplate)XamlReader.Parse( @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'> <Button Content='{Binding}' Height='100' /> </DataTemplate>"); var scrollViewer = new ScrollViewer() { Content = repeater }; scrollViewer.Height = 100; Content = scrollViewer; Content.UpdateLayout(); for (int i = 0; i < repeater.ItemsSourceView.Count; i++) { var child = repeater.TryGetElement(i) as Button; Verify.IsNotNull(child); } }); }
public void ValidateNonVirtualLayoutWithItemsRepeater() { RunOnUIThread.Execute(() => { var repeater = new ItemsRepeater(); repeater.Layout = new NonVirtualStackLayout(); repeater.ItemsSource = Enumerable.Range(0, 10); repeater.ItemTemplate = (DataTemplate)XamlReader.Parse( @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'> <Button Content='{Binding}' Height='100' /> </DataTemplate>"); Content = repeater; Content.UpdateLayout(); double expectedYOffset = 0; for (int i = 0; i < repeater.ItemsSourceView.Count; i++) { var child = repeater.TryGetElement(i) as Button; Verify.IsNotNull(child); var layoutBounds = LayoutInformation.GetLayoutSlot(child); Verify.AreEqual(expectedYOffset, layoutBounds.Y); Verify.AreEqual(i, child.Content); expectedYOffset += 100; } }); }
public void ValidateElementToIndexMapping() { ItemsRepeater repeater = null; RunOnUIThread.Execute(() => { var elementFactory = new RecyclingElementFactory(); elementFactory.RecyclePool = new RecyclePool(); elementFactory.Templates["Item"] = (DataTemplate)XamlReader.Parse( @"<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)), ItemTemplate = elementFactory, // 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)); }); }
public void VerifyUIElementsInItemsSource() { ItemsRepeater repeater = null; RunOnUIThread.Execute(() => { var scrollhost = (ItemsRepeaterScrollHost)XamlReader.Parse( @"<controls:ItemsRepeaterScrollHost xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:local='clr-namespace:MUXControlsTestApp.Samples;assembly=MUXControlsTestApp' xmlns:controls='http://schemas.modernwpf.com/2019'> <ScrollViewer> <controls:ItemsRepeater x:Name='repeater'> <controls:ItemsRepeater.ItemsSource> <local:UICollection> <Button>0</Button> <Button>1</Button> <Button>2</Button> <Button>3</Button> <Button>4</Button> <Button>5</Button> <Button>6</Button> <Button>7</Button> <Button>8</Button> <Button>9</Button> </local:UICollection> </controls:ItemsRepeater.ItemsSource> </controls:ItemsRepeater> </ScrollViewer> </controls:ItemsRepeaterScrollHost>"); repeater = (ItemsRepeater)scrollhost.FindName("repeater"); Content = scrollhost; }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { for (int i = 0; i < 10; i++) { var element = repeater.TryGetElement(i) as Button; Verify.AreEqual(i.ToString(), element.Content); } }); }
public void VerifyStoreScenarioCache() { ItemsRepeater rootRepeater = null; RunOnUIThread.Execute(() => { var scrollhost = (ItemsRepeaterScrollHost)XamlReader.Parse( @" <controls:ItemsRepeaterScrollHost Width='400' Height='200' xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' xmlns:controls='http://schemas.modernwpf.com/2019'> <controls:ItemsRepeaterScrollHost.Resources> <DataTemplate x:Key='ItemTemplate' > <TextBlock Text='{Binding}' Height='100' Width='100'/> </DataTemplate> <DataTemplate x:Key='GroupTemplate'> <StackPanel> <TextBlock Text='{Binding}' /> <controls:ItemsRepeaterScrollHost> <ScrollViewer HorizontalScrollBarVisibility='Auto' VerticalScrollBarVisibility='Hidden'> <controls:ItemsRepeater ItemTemplate='{StaticResource ItemTemplate}' ItemsSource='{Binding}'> <controls:ItemsRepeater.Layout> <controls:StackLayout Orientation='Horizontal' /> </controls:ItemsRepeater.Layout> </controls:ItemsRepeater> </ScrollViewer> </controls:ItemsRepeaterScrollHost> </StackPanel> </DataTemplate> </controls:ItemsRepeaterScrollHost.Resources> <ScrollViewer x:Name='scrollviewer'> <controls:ItemsRepeater x:Name='rootRepeater' ItemTemplate='{StaticResource GroupTemplate}'/> </ScrollViewer> </controls:ItemsRepeaterScrollHost>"); rootRepeater = (ItemsRepeater)scrollhost.FindName("rootRepeater"); 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; }); IdleSynchronizer.Wait(); // Verify that first items outside the visible range but in the realized range // for the inner of the nested repeaters are realized. RunOnUIThread.Execute(() => { // Group2 will be outside the visible range but within the realized range. var group2 = rootRepeater.TryGetElement(2) as StackPanel; Verify.IsNotNull(group2); var group2Repeater = ((ItemsRepeaterScrollHost)group2.Children[1]).ScrollViewer.Content as ItemsRepeater; Verify.IsNotNull(group2Repeater); Verify.IsNotNull(group2Repeater.TryGetElement(0)); }); }