diff --git a/dev/Breadcrumb/APITests/BreadcrumbTests.cs b/dev/Breadcrumb/APITests/BreadcrumbTests.cs index e65004b313..0d858fad0f 100644 --- a/dev/Breadcrumb/APITests/BreadcrumbTests.cs +++ b/dev/Breadcrumb/APITests/BreadcrumbTests.cs @@ -394,5 +394,69 @@ public void VerifyDropdownItemTemplateWithNoControl() } } + [TestMethod] + public void VerifyCollectionChangeGetsRespected() + { + BreadcrumbBar breadcrumb = null; + ItemsRepeater breadcrumbItemsRepeater = null; + RunOnUIThread.Execute(() => + { + // Set a custom ItemTemplate to be wrapped in a BreadcrumbBarItem. + var itemTemplate = (DataTemplate)XamlReader.Load( + @" + + + + + + + + "); + + + breadcrumb = new BreadcrumbBar(); + breadcrumb.ItemsSource = new List() { + new MockClass { MockProperty = "Node 1" }, + new MockClass { MockProperty = "Node 2" }, + }; + breadcrumb.ItemTemplate = itemTemplate; + + var stackPanel = new StackPanel(); + stackPanel.Children.Add(breadcrumb); + + Content = stackPanel; + Content.UpdateLayout(); + }); + + IdleSynchronizer.Wait(); + + RunOnUIThread.Execute(() => + { + breadcrumbItemsRepeater = (ItemsRepeater)breadcrumb.FindVisualChildByName("PART_ItemsRepeater"); + Verify.IsNotNull(breadcrumbItemsRepeater, "The underlying items repeater could not be retrieved"); + + var breadcrumbNode2 = breadcrumbItemsRepeater.TryGetElement(1) as BreadcrumbBarItem; + Verify.IsNotNull(breadcrumbNode2, "Our custom ItemTemplate should have been wrapped in a BreadcrumbBarItem."); + + breadcrumb.ItemsSource = new List() { + new MockClass { MockProperty = "Node 1" }, + new MockClass { MockProperty = "Node 2" }, + new MockClass { MockProperty = "Node 3" }, + new MockClass { MockProperty = "Node 4" }, + }; + }); + + IdleSynchronizer.Wait(); + + + RunOnUIThread.Execute(() => + { + var breadcrumbNode3 = breadcrumbItemsRepeater.TryGetElement(3) as BreadcrumbBarItem; + Verify.IsNotNull(breadcrumbNode3, "A fourth item should have been rendered by the BreadcrumControl"); + }); + } } } diff --git a/dev/Breadcrumb/BreadcrumbBar.cpp b/dev/Breadcrumb/BreadcrumbBar.cpp index 24c0f76e5d..bfd9f5ab1b 100644 --- a/dev/Breadcrumb/BreadcrumbBar.cpp +++ b/dev/Breadcrumb/BreadcrumbBar.cpp @@ -62,7 +62,7 @@ void BreadcrumbBar::OnApplyTemplate() itemsRepeater.Layout(*m_itemsRepeaterLayout); itemsRepeater.ItemsSource(winrt::make>()); itemsRepeater.ItemTemplate(*m_itemsRepeaterElementFactory); - + m_itemsRepeaterElementPreparedRevoker = itemsRepeater.ElementPrepared(winrt::auto_revoke, { this, &BreadcrumbBar::OnElementPreparedEvent }); m_itemsRepeaterElementIndexChangedRevoker = itemsRepeater.ElementIndexChanged(winrt::auto_revoke, { this, &BreadcrumbBar::OnElementIndexChangedEvent }); m_itemsRepeaterElementClearingRevoker = itemsRepeater.ElementClearing(winrt::auto_revoke, { this, &BreadcrumbBar::OnElementClearingEvent }); @@ -148,7 +148,11 @@ void BreadcrumbBar::UpdateItemsRepeaterItemsSource() if (ItemsSource()) { m_breadcrumbItemsSourceView = winrt::ItemsSourceView(ItemsSource()); - + if (const auto& itemsRepeater = m_itemsRepeater.get()) + { + m_itemsIterable = winrt::make_self(ItemsSource()); + itemsRepeater.ItemsSource(*m_itemsIterable); + } if (m_breadcrumbItemsSourceView) { m_itemsSourceChanged = m_breadcrumbItemsSourceView.CollectionChanged(winrt::auto_revoke, { this, &BreadcrumbBar::OnBreadcrumbBarItemsSourceCollectionChanged }); @@ -410,7 +414,7 @@ void BreadcrumbBar::OnGettingFocus(const winrt::IInspectable&, const winrt::Gett args.Handled(true); } } - } + } } // Focus was already in the repeater: in RS3+ Selection follows focus unless control is held down. @@ -568,8 +572,8 @@ void BreadcrumbBar::OnChildPreviewKeyDown(const winrt::IInspectable&, const winr args.Handled(true); return; } - else if ( (flowDirectionIsLTR && (args.OriginalKey() == winrt::VirtualKey::GamepadDPadRight)) || - (!flowDirectionIsLTR && (args.OriginalKey() == winrt::VirtualKey::GamepadDPadLeft)) ) + else if ((flowDirectionIsLTR && (args.OriginalKey() == winrt::VirtualKey::GamepadDPadRight)) || + (!flowDirectionIsLTR && (args.OriginalKey() == winrt::VirtualKey::GamepadDPadLeft))) { if (winrt::FocusManager::TryMoveFocus(winrt::FocusNavigationDirection::Next)) { @@ -588,7 +592,7 @@ void BreadcrumbBar::OnChildPreviewKeyDown(const winrt::IInspectable&, const winr return; } else if ((flowDirectionIsLTR && (args.OriginalKey() == winrt::VirtualKey::GamepadDPadLeft)) || - (!flowDirectionIsLTR && (args.OriginalKey() == winrt::VirtualKey::GamepadDPadRight))) + (!flowDirectionIsLTR && (args.OriginalKey() == winrt::VirtualKey::GamepadDPadRight))) { if (winrt::FocusManager::TryMoveFocus(winrt::FocusNavigationDirection::Previous)) {