Skip to content

Commit 389abe5

Browse files
committed
fix: inherited dc lifecycle
1 parent ad7047b commit 389abe5

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
using System.Threading.Tasks;
2+
using Microsoft.UI;
3+
using Microsoft.UI.Xaml;
4+
using Microsoft.UI.Xaml.Controls;
5+
using Microsoft.UI.Xaml.Media;
6+
using Uno.UI.Extensions;
7+
using Uno.UI.RuntimeTests.Helpers;
8+
9+
namespace Uno.UI.RuntimeTests.Tests.Windows_UI_Xaml;
10+
11+
partial class Given_UIElement
12+
{
13+
[TestMethod]
14+
[RunsOnUIThread]
15+
[PlatformCondition(ConditionMode.Include, RuntimeTestPlatforms.Skia)]
16+
public async Task When_Subtree_SeveredFromDataContextSource()
17+
{
18+
const int DC = 312;
19+
20+
var nested2 = new Border() { Name = "nested2" };
21+
var nested1 = new Border() { Name = "nested1", Child = nested2 };
22+
var host = new Border() { Name = "host", Child = nested1 };
23+
await UITestHelper.Load(host, x => x.IsLoaded);
24+
25+
host.DataContext = DC;
26+
Assert.AreEqual(DC, nested1.DataContext, "1. initially, DC (nested1) should be inherited");
27+
Assert.AreEqual(DC, nested2.DataContext, "1. initially, DC (nested2) should be inherited");
28+
29+
host.Child = null;
30+
Assert.IsNull(nested1.DataContext, "2. when detached, inherited DC(nested1) should be cleared");
31+
Assert.IsNull(nested2.DataContext, "2. when detached, inherited DC(nested2) should be cleared");
32+
33+
host.Child = nested1;
34+
Assert.AreEqual(DC, nested1.DataContext, "3. when reattached, DC (nested1) should be inherited again");
35+
Assert.AreEqual(DC, nested2.DataContext, "3. when reattached, DC (nested2) should be inherited again");
36+
}
37+
38+
[TestMethod]
39+
[RunsOnUIThread]
40+
[PlatformCondition(ConditionMode.Include, RuntimeTestPlatforms.Skia)]
41+
public async Task When_SeveredSubtree_ContainsDataContextSource()
42+
{
43+
const int DC = 312;
44+
45+
// v detachment point
46+
// H > N1 > N2 > N3 > N4
47+
// ^ DC owner, and propagation source
48+
// ^ + ^ inherited DC
49+
var nested4 = new Border() { Name = "nested4", };
50+
var nested3 = new Border() { Name = "nested3", Child = nested4 };
51+
var nested2 = new Border() { Name = "nested2", Child = nested3 };
52+
var nested1 = new Border() { Name = "nested1", Child = nested2 };
53+
var host = new Border() { Name = "host", Child = nested1 };
54+
await UITestHelper.Load(host, x => x.IsLoaded);
55+
56+
nested2.DataContext = DC;
57+
Assert.AreEqual(DC, nested3.DataContext, "1. initially, DC (nested3) should be inherited");
58+
Assert.AreEqual(DC, nested4.DataContext, "1. initially, DC (nested4) should be inherited");
59+
60+
host.Child = null;
61+
Assert.AreEqual(DC, nested3.DataContext, "2. when detached, DC (nested3) should still be inherited&unaffected");
62+
Assert.AreEqual(DC, nested4.DataContext, "2. when detached, DC (nested4) should still be inherited&unaffected");
63+
64+
host.Child = nested1;
65+
Assert.AreEqual(DC, nested3.DataContext, "3. when reattached, DC (nested3) should still be inherited&unaffected");
66+
Assert.AreEqual(DC, nested4.DataContext, "3. when reattached, DC (nested4) should still be inherited&unaffected");
67+
}
68+
}

src/Uno.UI/UI/Xaml/DependencyObjectStore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -644,7 +644,7 @@ private void TryApplyDataContextOnPrecedenceChange(
644644
}
645645

646646
[MethodImpl(MethodImplOptions.AggressiveInlining)]
647-
private void ClearInheritedDataContext()
647+
internal void ClearInheritedDataContext()
648648
{
649649
ClearValue(_dataContextProperty, DependencyPropertyValuePrecedences.Inheritance);
650650
}

src/Uno.UI/UI/Xaml/UIElement.crossruntime.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ private void OnChildAdded(UIElement child)
102102
private void OnChildRemoved(UIElement child)
103103
{
104104
child.Shutdown();
105+
(child as IDependencyObjectStoreProvider)?.Store.ClearInheritedDataContext();
105106

106107
#if UNO_HAS_ENHANCED_LIFECYCLE
107108
var leaveParams = new LeaveParams(IsActiveInVisualTree);

0 commit comments

Comments
 (0)