public void ValidateNoSizeWhenEmptyDataTemplate() { 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' />"); 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(), }; repeater.UpdateLayout(); // Asserting render size is zero Verify.IsLessThan(repeater.RenderSize.Width, 0.0001); Verify.IsLessThan(repeater.RenderSize.Height, 0.0001); }); }
private RecyclingElementFactory GetElementFactory() { var elementFactory = new RecyclingElementFactory(); elementFactory.RecyclePool = new RecyclePool(); elementFactory.Templates["Item"] = SharedHelpers.GetDataTemplate(@"<TextBlock Text='{Binding}' Height='100' />"); return(elementFactory); }
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 ScrollAnchorProvider() { Width = 200, Height = 200, Content = sv }; }); IdleSynchronizer.Wait(); scrollViewer = sv; return(repeater); }
private void OnSelectTemplateKey(RecyclingElementFactory sender, SelectTemplateEventArgs args) { args.TemplateKey = (int.Parse(args.DataContext.ToString()) % 2 == 0) ? "even" : "odd"; }
private void ElementFactory_SelectTemplateKey(RecyclingElementFactory sender, SelectTemplateEventArgs args) { args.TemplateKey = args.DataContext is IEnumerable ? "group" : "item"; }
private void OnSelectTemplateKey(RecyclingElementFactory sender, SelectTemplateEventArgs args) { args.TemplateKey = args.DataContext is string? "RepeaterItemTemplate" : "RepeaterGroupTemplate"; }
public void ValidateTabNavigation() { if (!PlatformConfiguration.IsOsVersionGreaterThan(OSVersion.Redstone2)) { Log.Warning("Test is disabled on anything lower than RS3 because the GetChildrenInTabFocusOrder API is not available on previous versions."); return; } ItemsRepeater repeater = null; ScrollViewer scrollViewer = null; var data = new ObservableCollection <string>(Enumerable.Range(0, 50).Select(i => "Item #" + i)); var viewChangedEvent = new AutoResetEvent(false); RunOnUIThread.Execute(() => { var itemTemplate = (DataTemplate)XamlReader.Load( @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'> <Button Content='{Binding}' Height='100' /> </DataTemplate>" ); var elementFactory = new RecyclingElementFactory() { RecyclePool = new RecyclePool(), Templates = { { "itemTemplate", itemTemplate }, } }; Content = CreateAndInitializeRepeater ( data, new StackLayout(), elementFactory, ref repeater, ref scrollViewer ); scrollViewer.ViewChanged += (s, e) => { if (!e.IsIntermediate) { viewChangedEvent.Set(); } }; repeater.TabFocusNavigation = KeyboardNavigationMode.Local; Content.UpdateLayout(); ValidateTabNavigationOrder(repeater); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { // Move window - disconnected scrollViewer.ChangeView(null, 2000, null, true); }); Verify.IsTrue(viewChangedEvent.WaitOne(DefaultWaitTimeInMS), "Waiting for final ViewChanged event."); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { ValidateTabNavigationOrder(repeater); // Delete a couple of elements and validate we // ignore unrealized elements. // First visible element is expected to be index 20. while (data.Count > 21) { data.RemoveAt(21); } repeater.UpdateLayout(); ValidateTabNavigationOrder(repeater); }); }
private void SetupRepeaterAnchoringUI( Scroller scroller, AutoResetEvent scrollerLoadedEvent) { Log.Comment("Setting up ItemsRepeater anchoring UI with Scroller and ItemsRepeater"); TestDataSource dataSource = new TestDataSource( Enumerable.Range(0, c_defaultAnchoringUIRepeaterChildrenCount).Select(i => string.Format("Item #{0}", i)).ToList()); RecyclingElementFactory elementFactory = new RecyclingElementFactory(); elementFactory.RecyclePool = new RecyclePool(); elementFactory.Templates["Item"] = XamlReader.Load( @"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'> <Border BorderThickness='3' BorderBrush='Chartreuse' Width='100' Height='100' Margin='3' Background='BlanchedAlmond'> <TextBlock Text='{Binding}' HorizontalAlignment='Center' VerticalAlignment='Center'/> </Border> </DataTemplate>") as DataTemplate; ItemsRepeater repeater = new ItemsRepeater() { Name = "repeater", ItemsSource = dataSource, #if BUILD_WINDOWS ItemTemplate = (Windows.UI.Xaml.IElementFactory)elementFactory, #else ItemTemplate = elementFactory, #endif Layout = new UniformGridLayout() { MinItemWidth = 125, MinItemHeight = 125, MinRowSpacing = 10, MinColumnSpacing = 10 }, Margin = new Thickness(30) }; Border border = new Border() { Name = "border", BorderThickness = new Thickness(3), BorderBrush = new SolidColorBrush(Colors.Chartreuse), Margin = new Thickness(15), Background = new SolidColorBrush(Colors.Beige), Child = repeater }; Verify.IsNotNull(scroller); scroller.Name = "scroller"; scroller.IsChildAvailableWidthConstrained = true; scroller.Width = 400; scroller.Height = 600; scroller.Background = new SolidColorBrush(Colors.AliceBlue); scroller.Child = border; if (scrollerLoadedEvent != null) { scroller.Loaded += (object sender, RoutedEventArgs e) => { Log.Comment("Scroller.Loaded event handler"); scrollerLoadedEvent.Set(); }; } scroller.AnchorRequested += (Scroller sender, ScrollerAnchorRequestedEventArgs args) => { Log.Comment("Scroller.AnchorRequested event handler"); Verify.IsNull(args.AnchorElement); Verify.IsGreaterThan(args.AnchorCandidates.Count, 0); }; Log.Comment("Setting window content"); MUXControlsTestApp.App.TestContentRoot = scroller; }
private void OnSelectTemplateKey(RecyclingElementFactory sender, SelectTemplateEventArgs args) { args.TemplateKey = (((int)args.DataContext) % 2 == 0) ? "even" : "odd"; }
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); }
private void OnSelectTemplateKey(RecyclingElementFactory sender, SelectTemplateEventArgs args) { args.TemplateKey = args.DataContext is Category ? "Category" : "Item"; }