public void ValidateChildRemovedFromParentWhenOwnerIsDifferent() { RunOnUIThread.Execute(() => { var element = new Button(); const string key1 = "Key1"; const string key2 = "Key2"; RecyclePool pool = new RecyclePool(); var parent1 = new StackPanel(); var child1 = new Button(); var child2 = new Button(); parent1.Children.Add(child1); parent1.Children.Add(child2); pool.PutElement(child1, key1); pool.PutElement(child2, key2); var parent2 = new StackPanel(); // Recycle the second child for a different parent. It should be disconnected var recycled1 = (FrameworkElement)pool.TryGetElement(key2, parent2); Verify.IsNull(recycled1.Parent); var recycled2 = (FrameworkElement)pool.TryGetElement(key1, parent2); Verify.IsNull(recycled2.Parent); }); }
protected override UIElement GetElementCore(ElementFactoryGetArgs args) #endif { var key = (args.Data is RecipeGroup) ? "Group" : "Recipe"; var element = (FrameworkElement)_recyclePool.TryGetElement(key, args.Parent); if (element == null) { if (args.Data is RecipeGroup) { element = (FrameworkElement)_groupTemplate.LoadContent(); _innerRepeaters.Add((ItemsRepeater)element.FindName("groupLayout")); } else { element = (FrameworkElement)_recipeTemplate.LoadContent(); } } element.Tag = key; if (args.Data is RecipeGroup) { var group = (RecipeGroup)args.Data; var groupName = (TextBlock)element.FindName("groupName"); var repeater = (ItemsRepeater)element.FindName("groupLayout"); groupName.Text = group.Name; var dataSource = new DelegatingItemsSource(group); dataSource.KeyFromIndexFunc = _KeyFromIndexFunc; repeater.ItemsSource = dataSource; repeater.Layout = IsInnerLayoutGrid ? (VirtualizingLayout) new UniformGridLayout() { MinItemWidth = 150, MinItemHeight = 150 } : (VirtualizingLayout) new StackLayout(); RepeaterTestHooks.SetLayoutId(repeater.Layout, group.Name); repeater.ItemTemplate = this; repeater.Animator = _animator; } else { var recipe = (Recipe)args.Data; var image = (Image)element.FindName("recipeImage"); var description = (TextBlock)element.FindName("recipeDescription"); image.Source = new BitmapImage(recipe.ImageUri); description.Text = recipe.Description; } return(element); }
public void ValidateOwnershipWithStackPanel() { RunOnUIThread.Execute(() => { RecyclePool pool = new RecyclePool(); var owner = new StackPanel(); var child = new Button(); owner.Children.Add(child); pool.PutElement(child, "Key", owner); var recycled = pool.TryGetElement("Key", owner); Verify.AreSame(child, recycled); Verify.AreEqual(0, owner.Children.IndexOf(child)); }); }
protected override UIElement GetElementCore(ElementFactoryGetArgs args) { var element = _recyclePool.TryGetElement(key, args.Parent); if (element == null) { element = new Button() { Width = 100, Height = 100 }; } var elementManager = new ElementPhasingManager(_numPhases); XamlBindingHelper.SetDataTemplateComponent(element, elementManager); return(element); }
public void ValidateElementsHaveCorrectKeys() { RunOnUIThread.Execute(() => { var element = new Button(); const string buttonKey = "ButtonKey"; const string textBlockKey = "TextBlockKey"; const string stackPanelKey = "StackPanelKey"; RecyclePool pool = new RecyclePool(); pool.PutElement(new Button(), buttonKey); pool.PutElement(new TextBlock(), textBlockKey); pool.PutElement(new StackPanel(), stackPanelKey); pool.PutElement(new Button(), buttonKey); pool.PutElement(new TextBlock(), textBlockKey); pool.PutElement(new StackPanel(), stackPanelKey); pool.PutElement(new Button(), buttonKey); pool.PutElement(new TextBlock(), textBlockKey); pool.PutElement(new StackPanel(), stackPanelKey); Verify.IsNotNull((Button)pool.TryGetElement(buttonKey)); Verify.IsNotNull((Button)pool.TryGetElement(buttonKey)); Verify.IsNotNull((Button)pool.TryGetElement(buttonKey)); Verify.IsNull(pool.TryGetElement(buttonKey)); Verify.IsNotNull((TextBlock)pool.TryGetElement(textBlockKey)); Verify.IsNotNull((TextBlock)pool.TryGetElement(textBlockKey)); Verify.IsNotNull((TextBlock)pool.TryGetElement(textBlockKey)); Verify.IsNull(pool.TryGetElement(textBlockKey)); Verify.IsNotNull((StackPanel)pool.TryGetElement(stackPanelKey)); Verify.IsNotNull((StackPanel)pool.TryGetElement(stackPanelKey)); Verify.IsNotNull((StackPanel)pool.TryGetElement(stackPanelKey)); Verify.IsNull(pool.TryGetElement(stackPanelKey)); Verify.Throws <COMException>(delegate { pool.PutElement(new Button(), null, null); }); Verify.Throws <COMException>(delegate { pool.PutElement(new Button(), buttonKey, new Button() /* not a panel */); }); Verify.Throws <COMException>(delegate { pool.TryGetElement(null, null); }); }); }
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 ScrollAnchorProvider() { Width = 400, Height = 400, Content = 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); } }); }