Skip to content

Commit

Permalink
Hide NavigationViewItem Chevron if Children is empty (microsoft/micro…
Browse files Browse the repository at this point in the history
  • Loading branch information
Kinnara committed Jul 3, 2020
1 parent 0fa6b69 commit 8857b72
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 1 deletion.
12 changes: 11 additions & 1 deletion ModernWpf.Controls/NavigationView/NavigationViewItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// Licensed under the MIT License. See LICENSE in the project root for license information.

using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Windows;
using System.Windows.Automation.Peers;
Expand Down Expand Up @@ -169,10 +170,17 @@ object init()
}
itemsSource = init();
}
m_itemsSourceViewCollectionChangedRevoker?.Revoke();
repeater.ItemsSource = itemsSource;
m_itemsSourceViewCollectionChangedRevoker = new ItemsSourceView.CollectionChanged_revoker(repeater.ItemsSourceView, OnItemsSourceViewChanged);
}
}

private void OnItemsSourceViewChanged(object sender, NotifyCollectionChangedEventArgs args)
{
UpdateVisualStateForChevron();
}

internal UIElement GetSelectionIndicator()
{
var selectIndicator = m_helper.GetSelectionIndicator();
Expand Down Expand Up @@ -493,7 +501,7 @@ void UpdateVisualStateForChevron()

internal bool HasChildren()
{
return MenuItems.Count > 0 || MenuItemsSource != null || HasUnrealizedChildren;
return MenuItems.Count > 0 || (MenuItemsSource != null && m_repeater.ItemsSourceView.Count > 0) || HasUnrealizedChildren;
}

bool ShouldShowIcon()
Expand Down Expand Up @@ -881,6 +889,7 @@ void UnhookEventsAndClearFields()
m_repeaterElementPreparedRevoker?.Revoke();
m_repeaterElementClearingRevoker?.Revoke();
IsEnabledChanged -= OnIsEnabledChanged;
m_itemsSourceViewCollectionChangedRevoker?.Revoke();

m_rootGrid = null;
m_navigationViewItemPresenter = null;
Expand All @@ -895,6 +904,7 @@ void UnhookEventsAndClearFields()

ItemsRepeaterElementPreparedRevoker m_repeaterElementPreparedRevoker;
ItemsRepeaterElementClearingRevoker m_repeaterElementClearingRevoker;
ItemsSourceView.CollectionChanged_revoker m_itemsSourceViewCollectionChangedRevoker;

FlyoutBaseClosingRevoker m_flyoutClosingRevoker;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,5 +88,24 @@ internal virtual int IndexOfCore(object value)
}

private int m_cachedSize = -1;

internal class CollectionChanged_revoker : EventRevoker<ItemsSourceView, NotifyCollectionChangedEventHandler>
{
public CollectionChanged_revoker(ItemsSourceView source, NotifyCollectionChangedEventHandler handler) : base(source, handler)
{
}

protected override void AddHandler(ItemsSourceView source, NotifyCollectionChangedEventHandler handler)
{
source.CollectionChanged += handler;
}

protected override void RemoveHandler(ItemsSourceView source, NotifyCollectionChangedEventHandler handler)
{
source.CollectionChanged -= handler;
}
}
}


}
1 change: 1 addition & 0 deletions ModernWpf/Common/EventRevoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ internal abstract class EventRevoker<TSource, TDelegate>
public EventRevoker(TSource source, TDelegate handler)
{
_source = new WeakReference<TSource>(source);
_handler = new WeakReference<TDelegate>(handler);
AddHandler(source, handler);
}

Expand Down
62 changes: 62 additions & 0 deletions test/ModernWpfTestApp/ApiTests/NavigationViewTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -798,5 +798,67 @@ public void VerifyNavigationViewItemInFooterDoesNotCrash()
Verify.IsTrue(true);
});
}

[TestMethod]
public void VerifyExpandCollapseChevronVisibility()
{
NavigationView navView = null;
NavigationViewItem parentItem = null;
ObservableCollection<string> children = null;

RunOnUIThread.Execute(() =>
{
navView = new NavigationView();
Content = navView;
children = new ObservableCollection<string>();
parentItem = new NavigationViewItem() { Content = "ParentItem", MenuItemsSource = children };
navView.MenuItems.Add(parentItem);
navView.Width = 1008; // forces the control into Expanded mode so that the menu renders
Content.UpdateLayout(true);
UIElement chevronUIElement = (UIElement)VisualTreeUtils.FindVisualChildByName(parentItem, "ExpandCollapseChevron");
Verify.IsTrue(chevronUIElement.Visibility == Visibility.Collapsed, "chevron should have been collapsed as NavViewItem has no children");
// Add a child to parentItem through the MenuItemsSource API. This should make the chevron visible.
children.Add("Child 1");
Content.UpdateLayout(true);
Verify.IsTrue(chevronUIElement.Visibility == Visibility.Visible, "chevron should have been visible as NavViewItem now has children");
// Remove all children of parentItem. This should collapse the chevron
children.Clear();
Content.UpdateLayout(true);
Verify.IsTrue(chevronUIElement.Visibility == Visibility.Collapsed, "chevron should have been collapsed as NavViewItem no longer has children");
// Add a child to parentItem and set the MenuItemsSource as null. This should collapse the chevron
children.Add("Child 2");
Content.UpdateLayout(true);
// we are doing this so that when we set MenuItemsSource as null, we can check if the chevron's visibility really changes
Verify.IsTrue(chevronUIElement.Visibility == Visibility.Visible, "chevron should have been visible as NavViewItem now has children");
parentItem.MenuItemsSource = null;
Content.UpdateLayout(true);
Verify.IsTrue(chevronUIElement.Visibility == Visibility.Collapsed, "chevron should have been collapsed as NavViewItem no longer has children");
// Add a child to parentItem through the MenuItems API. This should make the chevron visible.
parentItem.MenuItems.Add(new NavigationViewItem() { Content = "Child 3" });
Content.UpdateLayout(true);
Verify.IsTrue(chevronUIElement.Visibility == Visibility.Visible, "chevron should have been visible as NavViewItem now has children");
// Remove all children of parentItem. This should collapse the chevron
parentItem.MenuItems.Clear();
Content.UpdateLayout(true);
Verify.IsTrue(chevronUIElement.Visibility == Visibility.Collapsed, "chevron should have been collapsed as NavViewItem no longer has children");
});
}

}
}

0 comments on commit 8857b72

Please sign in to comment.