public void CanResetLayoutAfterUniqueIdReset() { var data = new WinRTCollection(Enumerable.Range(0, 2).Select(i => string.Format("Item #{0}", i))); object dataSource = null; RunOnUIThread.Execute(() => dataSource = MockItemsSource.CreateDataSource(data, supportsUniqueIds: true)); ItemsRepeater repeater = SetupRepeater(dataSource); RunOnUIThread.Execute(() => { var range = new UIElement[] { repeater.TryGetElement(0), repeater.TryGetElement(1) }; var clearedElements = new List <UIElement>(); repeater.ElementClearing += (s, e) => { clearedElements.Add(e.Element); }; // The realized elements will be sent to the unique id reset pool. // They haven't been cleared yet. data.Reset(); Verify.AreEqual(0, clearedElements.Count); // This also cause elements to be sent to the unique id reset pool. // We are validating here that we are smart enough not send them there twice. // Doing so will cause an exception to be thrown. repeater.Layout = null; Verify.AreEqual(0, clearedElements.Count); repeater.UpdateLayout(); // Layout runs. The elements in the reset pool are not used. // They should be cleared back to the view generator at this point. Verify.AreEqual(2, clearedElements.Count); Verify.AreEqual(range[0], clearedElements[0]); Verify.AreEqual(range[1], clearedElements[1]); Verify.IsNull(repeater.TryGetElement(0)); Verify.IsNull(repeater.TryGetElement(1)); }); }
public void CanChangeFocusAfterUniqueIdReset() { var data = new WinRTCollection(Enumerable.Range(0, 2).Select(i => string.Format("Item #{0}", i))); object dataSource = null; RunOnUIThread.Execute(() => dataSource = MockItemsSource.CreateDataSource(data, supportsUniqueIds: true)); ItemsRepeater repeater = SetupRepeater(dataSource); Control focusedElement = null; RunOnUIThread.Execute(() => { focusedElement = (Control)repeater.TryGetElement(0); focusedElement.Focus(FocusState.Keyboard); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { data.Reset(); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { // Still focused. Verify.AreEqual(focusedElement, FocusManager.GetFocusedElement()); // Change focused element. focusedElement = (Control)repeater.TryGetElement(1); focusedElement.Focus(FocusState.Keyboard); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { // Focus is on the new element. Verify.AreEqual(focusedElement, FocusManager.GetFocusedElement()); }); }
// [TestMethod] Issue 1018 public void CanReuseElementsDuringUniqueIdReset() { var data = new WinRTCollection(Enumerable.Range(0, 2).Select(i => string.Format("Item #{0}", i))); List <UIElement> mapping = null; ItemsRepeater repeater = null; MockElementFactory elementFactory = null; ContentControl focusedElement = null; RunOnUIThread.Execute(() => { mapping = new List <UIElement> { new ContentControl(), new ContentControl() }; repeater = CreateRepeater( MockItemsSource.CreateDataSource(data, supportsUniqueIds: true), MockElementFactory.CreateElementFactory(mapping)); elementFactory = (MockElementFactory)repeater.ItemTemplate; Content = repeater; repeater.UpdateLayout(); focusedElement = (ContentControl)repeater.TryGetElement(1); focusedElement.Focus(FocusState.Keyboard); }); IdleSynchronizer.Wait(); RunOnUIThread.Execute(() => { elementFactory.ValidateGetElementCalls( new MockElementFactory.GetElementCallInfo(0, repeater), new MockElementFactory.GetElementCallInfo(1, repeater)); elementFactory.ValidateRecycleElementCalls(); data.ResetWith(new[] { data[0], "New item" }); Verify.AreEqual(0, repeater.GetElementIndex(mapping[0])); Verify.AreEqual(1, repeater.GetElementIndex(mapping[1])); Verify.IsNull(repeater.TryGetElement(0)); Verify.IsNull(repeater.TryGetElement(1)); elementFactory.ValidateGetElementCalls(/* GetElement should not be called */); elementFactory.ValidateRecycleElementCalls(/* RecycleElement should not be called */); mapping[1] = new ContentControl(); // For "New Item" repeater.UpdateLayout(); Verify.AreEqual(0, repeater.GetElementIndex(mapping[0])); Verify.AreEqual(1, repeater.GetElementIndex(mapping[1])); Verify.AreEqual(mapping[0], repeater.TryGetElement(0)); Verify.AreEqual(mapping[1], repeater.TryGetElement(1)); elementFactory.ValidateGetElementCalls( new MockElementFactory.GetElementCallInfo(1, repeater)); elementFactory.ValidateRecycleElementCalls( new MockElementFactory.RecycleElementCallInfo(focusedElement, repeater)); // If the focused element survived the reset, we will keep focus on it. If not, we // try to find one based on the index. In this case, the focused element (index 1) // got recycled, and we still have index 1 after the stable reset, so the new index 1 // will get focused. Note that recycling the elements to view generator in the case of // stable reset happens during the arrange, so by that time we will have pulled elements // from the stable reset pool and maybe created some new elements as well. int index = repeater.GetElementIndex(focusedElement); Log.Comment("focused index " + index); Verify.AreEqual(mapping[1], FocusManager.GetFocusedElement()); }); }