Skip to content

Commit

Permalink
[BreadcrumbBar] Fix issue where setting ItemsSource was not respected (
Browse files Browse the repository at this point in the history
…#6316)

* Add test

* Fix bug

* Remove unused import
  • Loading branch information
marcelwgn authored Feb 10, 2022
1 parent d409845 commit 9aedb00
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 6 deletions.
64 changes: 64 additions & 0 deletions dev/Breadcrumb/APITests/BreadcrumbTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
@"<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:controls='using:Microsoft.UI.Xaml.Controls'
xmlns:local='using:Windows.UI.Xaml.Tests.MUXControls.ApiTests'>
<controls:BreadcrumbBarItem Content='{Binding}'>
<controls:BreadcrumbBarItem.ContentTemplate>
<DataTemplate>
<TextBlock Text='{Binding MockProperty}'/>
</DataTemplate>
</controls:BreadcrumbBarItem.ContentTemplate>
</controls:BreadcrumbBarItem>
</DataTemplate>");
breadcrumb = new BreadcrumbBar();
breadcrumb.ItemsSource = new List<MockClass>() {
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<MockClass>() {
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");
});
}
}
}
16 changes: 10 additions & 6 deletions dev/Breadcrumb/BreadcrumbBar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void BreadcrumbBar::OnApplyTemplate()
itemsRepeater.Layout(*m_itemsRepeaterLayout);
itemsRepeater.ItemsSource(winrt::make<Vector<IInspectable>>());
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 });
Expand Down Expand Up @@ -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<BreadcrumbIterable>(ItemsSource());
itemsRepeater.ItemsSource(*m_itemsIterable);
}
if (m_breadcrumbItemsSourceView)
{
m_itemsSourceChanged = m_breadcrumbItemsSourceView.CollectionChanged(winrt::auto_revoke, { this, &BreadcrumbBar::OnBreadcrumbBarItemsSourceCollectionChanged });
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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))
{
Expand All @@ -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))
{
Expand Down

0 comments on commit 9aedb00

Please sign in to comment.