Skip to content

Commit 733009d

Browse files
committed
fix(droid): add workaround for NavView leaving blank on IsBackButtonVisible update
1 parent 9252761 commit 733009d

File tree

2 files changed

+125
-10
lines changed

2 files changed

+125
-10
lines changed

src/Uno.UI.RuntimeTests/Tests/Microsoft_UI_Xaml_Controls/Given_NavigationView.cs

Lines changed: 113 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,24 @@
1-
using System.Threading.Tasks;
2-
#if WINAPPSDK
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Threading.Tasks;
5+
using Microsoft.UI.Xaml;
6+
using Microsoft.UI.Xaml.Controls;
7+
using Microsoft.UI.Xaml.Media;
8+
using Windows.UI;
9+
using Uno.Extensions;
10+
using Uno.Extensions.Specialized;
311
using Uno.UI.Extensions;
4-
#elif __IOS__
12+
using Uno.UI.RuntimeTests.Helpers;
13+
14+
using static Private.Infrastructure.TestServices;
15+
using MUXC = Microsoft/* UWP don't rename */.UI.Xaml.Controls;
16+
17+
#if __IOS__
518
using UIKit;
619
#elif __MACOS__
720
using AppKit;
8-
#else
921
#endif
10-
using Microsoft.UI.Xaml;
11-
using Microsoft.UI.Xaml.Controls;
12-
using static Private.Infrastructure.TestServices;
13-
using Windows.UI;
14-
using Microsoft.UI.Xaml.Media;
15-
using Uno.UI.RuntimeTests.Helpers;
1622

1723
namespace Uno.UI.RuntimeTests.Tests.Microsoft_UI_Xaml_Controls
1824
{
@@ -73,5 +79,102 @@ public async Task When_SelectedItem_Set_Before_Load_And_Theme_Changed()
7379
#endif
7480
}
7581
}
82+
83+
[TestMethod]
84+
public async Task When_IsBackButtonVisible_Toggled()
85+
{
86+
// unoplatform/uno#19516
87+
// droid-specific: There is a bug where setting IsBackButtonVisible would "lock" the size of all NVIs
88+
// preventing resizing on items expansion/collapse.
89+
90+
var sut = new MUXC.NavigationView()
91+
{
92+
Height = 500,
93+
IsBackButtonVisible = MUXC.NavigationViewBackButtonVisible.Collapsed,
94+
IsPaneToggleButtonVisible = false,
95+
PaneDisplayMode = NavigationViewPaneDisplayMode.Left,
96+
CompactModeThresholdWidth = 10,
97+
ExpandedModeThresholdWidth = 50,
98+
};
99+
sut.ItemInvoked += (s, e) =>
100+
{
101+
// manual trigger for deepest/inner-most items
102+
if (e.InvokedItemContainer is NavigationViewItem nvi &&
103+
nvi.MenuItems.Count == 0)
104+
{
105+
sut.IsBackButtonVisible = NavigationViewBackButtonVisible.Visible;
106+
}
107+
};
108+
109+
var nvis = new Dictionary<string, NavigationViewItem>();
110+
//AddItems(sut.MenuItems, "", count: 4, depth: 1, maxDepth: 2);
111+
AddItems(sut.MenuItems, "", count: 3, depth: 1, maxDepth: 3);
112+
void AddItems(IList<object> target, string prefix, int count, int depth, int maxDepth)
113+
{
114+
for (int i = 0; i < count; i++)
115+
{
116+
var header = prefix + (char)('A' + i);
117+
var item = new NavigationViewItem() { Content = header };
118+
119+
if (depth < maxDepth) AddItems(item.MenuItems, header, count, depth + 1, maxDepth);
120+
121+
target.Add(item);
122+
nvis.Add(header, item);
123+
}
124+
}
125+
126+
// for debugging
127+
var panel = new StackPanel();
128+
void AddTestButton(string label, Action action)
129+
{
130+
var button = new Button() { Content = label };
131+
button.Click += (s, e) => action();
132+
panel.Children.Add(button);
133+
}
134+
AddTestButton("InvalidateMeasure", () =>
135+
{
136+
foreach (var ir in sut.EnumerateDescendants().OfType<ItemsRepeater>())
137+
{
138+
ir.InvalidateMeasure();
139+
}
140+
});
141+
AddTestButton("IsBackButtonVisible toggle", () => sut.IsBackButtonVisible = sut.IsBackButtonVisible == NavigationViewBackButtonVisible.Collapsed
142+
? NavigationViewBackButtonVisible.Visible
143+
: NavigationViewBackButtonVisible.Collapsed);
144+
panel.Children.Add(sut);
145+
146+
await UITestHelper.Load(panel, x => x.IsLoaded);
147+
148+
var initialHeight = nvis["B"].ActualHeight;
149+
150+
nvis["B"].IsExpanded = true;
151+
await UITestHelper.WaitForIdle();
152+
var partiallyExpandedHeight = nvis["B"].ActualHeight;
153+
154+
nvis["BB"].IsExpanded = true;
155+
await UITestHelper.WaitForIdle();
156+
var fullyExpandedHeight = nvis["B"].ActualHeight;
157+
158+
// trigger the bug
159+
await Task.Delay(2000); // necessary
160+
sut.IsBackButtonVisible = NavigationViewBackButtonVisible.Visible;
161+
await UITestHelper.WaitForIdle();
162+
163+
nvis["BB"].IsExpanded = false;
164+
await UITestHelper.WaitForIdle();
165+
var partiallyCollapsedHeight = nvis["B"].ActualHeight;
166+
167+
nvis["B"].IsExpanded = false;
168+
await UITestHelper.WaitForIdle();
169+
var fullyCollapsedHeight = nvis["B"].ActualHeight;
170+
171+
// sanity check
172+
Assert.IsTrue(initialHeight < partiallyExpandedHeight, $"Expanding 'B' should increase item 'B' height: {initialHeight} -> {partiallyExpandedHeight}");
173+
Assert.IsTrue(partiallyExpandedHeight < fullyExpandedHeight, $"Expanding 'BB' should increase item 'B' height: {partiallyExpandedHeight} -> {fullyExpandedHeight}");
174+
175+
// verifying fix
176+
Assert.IsTrue(fullyExpandedHeight > partiallyCollapsedHeight, $"Collapsing 'BB' should reduce item 'B' height: {fullyExpandedHeight} -> {partiallyCollapsedHeight}");
177+
Assert.IsTrue(partiallyCollapsedHeight > fullyCollapsedHeight, $"Collapsing 'B' should reduce item 'B' height: {partiallyCollapsedHeight} -> {fullyCollapsedHeight}");
178+
}
76179
}
77180
}

src/Uno.UI/Microsoft/UI/Xaml/Controls/NavigationView/NavigationView.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,14 @@
99
using System.Collections.ObjectModel;
1010
using System.Collections.Specialized;
1111
using System.Globalization;
12+
using System.Linq;
1213
using System.Numerics;
1314
using Microsoft/* UWP don't rename */.UI.Xaml.Automation.Peers;
1415
using Microsoft/* UWP don't rename */.UI.Xaml.Controls.AnimatedVisuals;
1516
using Uno.Disposables;
1617
using Uno.Foundation.Logging;
1718
using Uno.UI.DataBinding;
19+
using Uno.UI.Extensions;
1820
using Uno.UI.Helpers.WinUI;
1921
using Windows.ApplicationModel.Core;
2022
using Windows.Foundation;
@@ -4353,6 +4355,16 @@ private void OnPropertyChanged(DependencyPropertyChangedEventArgs args)
43534355
{
43544356
backButton.UpdateLayout();
43554357
}
4358+
4359+
// workaround for unoplatform/uno#19516 where toggling IsBackButtonVisible would lock the size of all NVIs
4360+
if (m_appliedTemplate && IsLoaded)
4361+
{
4362+
foreach (var ir in this.EnumerateDescendants().OfType<ItemsRepeater>())
4363+
{
4364+
ir.InvalidateMeasure();
4365+
}
4366+
}
4367+
43564368
UpdatePaneLayout();
43574369
}
43584370

0 commit comments

Comments
 (0)