Skip to content

Commit 02eada5

Browse files
committed
chore: Failling trial for Android/iOS. Keeping the commit just for future reference
1 parent a0a0d7c commit 02eada5

11 files changed

+142
-46
lines changed

src/Uno.UI/Controls/BindableUIView.iOS.cs

+11
Original file line numberDiff line numberDiff line change
@@ -47,16 +47,27 @@ public override void AddSubview(UIView view)
4747
// Instead we have to pre-update the _shadowChildren so handlers of the Loaded event will be able
4848
// to properly walk the tree up and down (cf. EffectiveViewport).
4949
_shadowChildren.Add(view);
50+
TryRegisterName(view);
5051
base.AddSubview(view);
5152
}
5253

5354
public override void InsertSubview(UIView view, nint atIndex)
5455
{
5556
// cf. AddSubview comment!
5657
_shadowChildren.Insert((int)atIndex, view);
58+
TryRegisterName(view);
5759
base.InsertSubview(view, atIndex);
5860
}
5961

62+
private void TryRegisterName(UIView view)
63+
{
64+
if (view is FrameworkElement { Name: { Length: > 0 } name } fe &&
65+
FindNameScope(fe) is { } nameScope)
66+
{
67+
nameScope.RegisterName(name, fe);
68+
}
69+
}
70+
6071
public override void WillRemoveSubview(UIView uiview)
6172
{
6273
// cf. AddSubview comment!

src/Uno.UI/UI/Xaml/EnterParams.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#if UNO_HAS_ENHANCED_LIFECYCLE
2-
namespace Uno.UI.Xaml;
1+
namespace Uno.UI.Xaml;
32

43
internal struct EnterParams
54
{
@@ -15,4 +14,3 @@ public EnterParams(bool isLive)
1514
IsLive = isLive;
1615
}
1716
}
18-
#endif

src/Uno.UI/UI/Xaml/FrameworkElement.Layout.crossruntime.cs

+3-13
Original file line numberDiff line numberDiff line change
@@ -902,14 +902,6 @@ private void ArrangeNative(Point offset, Rect? clippedFrame)
902902
#endif
903903
}
904904

905-
private void AdjustNameScope(ref INameScope? nameScope)
906-
{
907-
if (NameScope.GetNameScope(this) is { } currentNameScope)
908-
{
909-
nameScope = currentNameScope;
910-
}
911-
}
912-
913905
internal override void Enter(INameScope? nameScope, EnterParams @params, int depth)
914906
{
915907
// This should happen regardless of whether Name is null or not.
@@ -922,11 +914,9 @@ internal override void Enter(INameScope? nameScope, EnterParams @params, int dep
922914
{
923915
var name = this.Name;
924916

925-
if (!string.IsNullOrEmpty(name) && nameScope.FindName(name) is null)
917+
if (!string.IsNullOrEmpty(name))
926918
{
927-
// Ideally, we shouldn't be checking for null FindName.
928-
// But it's currently needed due to the way we
929-
// register names in namescopes which don't yet match WinUI completely.
919+
// NOTE: Multiple RegisterName calls can happen.
930920
// Right now, XAML generator will do RegisterName calls, then, when we
931921
// enter the visual tree, we will be trying to register the name again.
932922
// However, registering in Enter is also very necessary in case C# is used
@@ -935,7 +925,7 @@ internal override void Enter(INameScope? nameScope, EnterParams @params, int dep
935925
// The RegisterName calls in XAML generator should probably happen via something
936926
// similar to WinUI's PostParseRegisterNames which will basically just do an "Enter" with
937927
// isLive being false. Then, the Enter happening in VisualTree.AddRoot should skip name registration.
938-
nameScope.RegisterName(name, this);
928+
((NameScope)nameScope).RegisterNameNoWarn(name, this);
939929
}
940930
}
941931

src/Uno.UI/UI/Xaml/FrameworkElement.cs

+63
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
using Uno.UI.Xaml.Controls;
2929
using Uno.UI.Xaml.Core;
3030
using Uno.UI.Xaml.Media;
31+
using Microsoft.UI.Xaml.Markup;
32+
3133

3234
#if __ANDROID__
3335
using View = Android.Views.View;
@@ -941,6 +943,67 @@ internal virtual void UpdateThemeBindings(ResourceUpdateReason updateReason)
941943
}
942944
}
943945

946+
private void AdjustNameScope(ref INameScope nameScope)
947+
{
948+
if (NameScope.GetNameScope(this) is { } currentNameScope)
949+
{
950+
nameScope = currentNameScope;
951+
}
952+
}
953+
954+
#if !UNO_HAS_ENHANCED_LIFECYCLE
955+
internal override void Enter(INameScope nameScope, EnterParams @params, int depth)
956+
{
957+
// This should happen regardless of whether Name is null or not.
958+
// What we need here is that once we find an element being entered that
959+
// has its own NameScope, then we start using this namescope and use it for entering its children.
960+
// For example, elements in a template where the template root will have its own NameScope.
961+
AdjustNameScope(ref nameScope);
962+
963+
if (nameScope is not null)
964+
{
965+
var name = this.Name;
966+
967+
if (!string.IsNullOrEmpty(name))
968+
{
969+
// NOTE: Multiple RegisterName calls can happen.
970+
// Right now, XAML generator will do RegisterName calls, then, when we
971+
// enter the visual tree, we will be trying to register the name again.
972+
// However, registering in Enter is also very necessary in case C# is used
973+
// instead of XAML (be it "regular" C# code or C# Markup).
974+
// So, we need to have RegisterName here.
975+
// The RegisterName calls in XAML generator should probably happen via something
976+
// similar to WinUI's PostParseRegisterNames which will basically just do an "Enter" with
977+
// isLive being false. Then, the Enter happening in VisualTree.AddRoot should skip name registration.
978+
((NameScope)nameScope).RegisterNameNoWarn(name, this);
979+
}
980+
}
981+
982+
base.Enter(nameScope, @params, depth);
983+
}
984+
985+
internal override void Leave(INameScope nameScope, LeaveParams @params)
986+
{
987+
// This should happen regardless of whether Name is null or not.
988+
// What we need here is that once we find an element leaving that
989+
// has its own NameScope, then we start using this namescope and use it for leaving its children.
990+
// For example, elements in a template where the template root will have its own NameScope.
991+
AdjustNameScope(ref nameScope);
992+
993+
if (nameScope is not null)
994+
{
995+
var name = this.Name;
996+
997+
if (!string.IsNullOrEmpty(name))
998+
{
999+
nameScope.UnregisterName(name);
1000+
}
1001+
}
1002+
1003+
base.Leave(nameScope, @params);
1004+
}
1005+
#endif
1006+
9441007
#region AutomationPeer
9451008
#if !__IOS__ && !__ANDROID__ && !__MACOS__ // This code is generated in FrameworkElementMixins
9461009
private AutomationPeer _automationPeer;

src/Uno.UI/UI/Xaml/Internal/VisualTree.cs

-2
Original file line numberDiff line numberDiff line change
@@ -457,15 +457,13 @@ private void AddRoot(UIElement? root)
457457
MUX_ASSERT(RootElement != null);
458458
RootElement!.AddChild(root);
459459

460-
#if UNO_HAS_ENHANCED_LIFECYCLE
461460
EnterParams enterParams = new(
462461
isLive: true
463462
);
464463

465464
// In WinUI, this is called only under IsMainVisualTree condition.
466465
// This might be needed for now in Uno because RootVisual does not *yet* have XamlIslandRootCollection
467466
root.Enter(NameScope.GetNameScope(root), enterParams, 0);
468-
#endif
469467
}
470468
}
471469

src/Uno.UI/UI/Xaml/LeaveParams.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
#if UNO_HAS_ENHANCED_LIFECYCLE
2-
namespace Uno.UI.Xaml;
1+
namespace Uno.UI.Xaml;
32

43
internal struct LeaveParams
54
{
@@ -15,4 +14,3 @@ public LeaveParams(bool isLive)
1514
IsLive = isLive;
1615
}
1716
}
18-
#endif

src/Uno.UI/UI/Xaml/NameScope.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,23 @@ public object FindName(string name)
4242

4343
public void RegisterName(string name, object scopedElement)
4444
{
45-
if (_names.ContainsKey(name))
45+
if (this.Log().IsEnabled(LogLevel.Warning) && _names.ContainsKey(name))
4646
{
4747
this.Log().Warn($"The name [{name}] already exists in the current XAML scope");
4848
}
4949

5050
_names[name] = WeakReferencePool.RentWeakReference(this, scopedElement);
5151
}
5252

53+
internal void RegisterNameNoWarn(string name, object scopedElement)
54+
{
55+
if (name == "textBox")
56+
{
57+
58+
}
59+
_names[name] = WeakReferencePool.RentWeakReference(this, scopedElement);
60+
}
61+
5362
public void UnregisterName(string name)
5463
{
5564
_names.Remove(name);

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

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
using Rect = Windows.Foundation.Rect;
1919
using Java.Interop;
2020
using Microsoft.UI.Xaml.Markup;
21+
using Uno.UI.Xaml;
2122

2223
namespace Microsoft.UI.Xaml
2324
{
@@ -65,6 +66,7 @@ protected override void OnChildViewAdded(View view)
6566
if (view is UIElement uiElement)
6667
{
6768
OnChildManagedViewAddedOrRemoved(uiElement);
69+
uiElement.Enter(FindNameScope(uiElement), default, default);
6870
}
6971
else
7072
{
@@ -80,6 +82,7 @@ protected override void OnChildViewRemoved(View view)
8082
if (view is UIElement uiElement)
8183
{
8284
OnChildManagedViewAddedOrRemoved(uiElement);
85+
uiElement.Leave(FindNameScope(uiElement), default);
8386
}
8487
else
8588
{

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

-19
Original file line numberDiff line numberDiff line change
@@ -118,25 +118,6 @@ internal Point GetPosition(Point position, UIElement relativeTo)
118118
=> TransformToVisual(relativeTo).TransformPoint(position);
119119

120120
#if UNO_HAS_ENHANCED_LIFECYCLE
121-
internal static INameScope FindNameScope(DependencyObject dependencyObject)
122-
{
123-
// In many cases, this will not traverse the entire visual tree, as the NameScope is often
124-
// present on each element as the DP is inherited. However, it can happen that the DP inheritance
125-
// didn't yet happen, in which case we'll traverse the tree up.
126-
var current = dependencyObject;
127-
while (current is not null)
128-
{
129-
if (NameScope.GetNameScope(current) is { } nameScope)
130-
{
131-
return nameScope;
132-
}
133-
134-
current = VisualTreeHelper.GetParent(current);
135-
}
136-
137-
return null;
138-
}
139-
140121
private void ChildEnter(UIElement child, EnterParams @params)
141122
{
142123
// Uno TODO: WinUI has much more complex logic than this.

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

+19
Original file line numberDiff line numberDiff line change
@@ -1434,6 +1434,25 @@ internal void SetProtectedCursor(Microsoft /* UWP don't rename */.UI.Input.Input
14341434
ProtectedCursor = cursor;
14351435
}
14361436

1437+
internal static INameScope FindNameScope(DependencyObject dependencyObject)
1438+
{
1439+
// In many cases, this will not traverse the entire visual tree, as the NameScope is often
1440+
// present on each element as the DP is inherited. However, it can happen that the DP inheritance
1441+
// didn't yet happen, in which case we'll traverse the tree up.
1442+
var current = dependencyObject;
1443+
while (current is not null)
1444+
{
1445+
if (NameScope.GetNameScope(current) is { } nameScope)
1446+
{
1447+
return nameScope;
1448+
}
1449+
1450+
current = VisualTreeHelper.GetParent(current);
1451+
}
1452+
1453+
return null;
1454+
}
1455+
14371456
/// <summary>
14381457
/// This event is not yet implemented in Uno Platform.
14391458
/// </summary>

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

+31-5
Original file line numberDiff line numberDiff line change
@@ -616,18 +616,27 @@ internal Rect GetGlobalBoundsWithOptions(bool ignoreClipping, bool ignoreClippin
616616
return new Rect();
617617
}
618618

619-
#if UNO_HAS_ENHANCED_LIFECYCLE
620619
// Doesn't exactly match WinUI code.
621620
internal virtual void Enter(INameScope? nameScope, EnterParams @params, int depth)
622621
{
622+
// Enter does nothing on platforms with non-enhanced lifecycle.
623+
// Its only purpose is to register names via the FrameworkElement override.
624+
#if UNO_HAS_ENHANCED_LIFECYCLE
623625
Depth = depth;
624626

625627
if (@params.IsLive)
626628
{
627629
IsActiveInVisualTree = true;
628630
}
631+
#endif
632+
633+
#if UNO_HAS_ENHANCED_LIFECYCLE
634+
var children = _children;
635+
#else
636+
var children = this.GetChildren();
637+
#endif
629638

630-
foreach (var child in _children)
639+
foreach (var child in children)
631640
{
632641
if (child == this)
633642
{
@@ -639,9 +648,14 @@ internal virtual void Enter(INameScope? nameScope, EnterParams @params, int dept
639648
continue;
640649
}
641650

651+
#if UNO_HAS_ENHANCED_LIFECYCLE
642652
child.Enter(nameScope, @params, depth + 1);
653+
#else
654+
(child as UIElement)?.Enter(nameScope, @params, depth + 1);
655+
#endif
643656
}
644657

658+
#if UNO_HAS_ENHANCED_LIFECYCLE
645659
if (@params.IsLive)
646660
{
647661
var core = this.GetContext();
@@ -650,11 +664,19 @@ internal virtual void Enter(INameScope? nameScope, EnterParams @params, int dept
650664

651665
// Make sure that we propagate OnDirtyPath bits to the new parent.
652666
SetLayoutFlags(LayoutFlag.MeasureDirty | LayoutFlag.ArrangeDirty);
667+
#endif
653668
}
654669

655670
internal virtual void Leave(INameScope? nameScope, LeaveParams @params)
656671
{
657-
foreach (var child in _children)
672+
var children =
673+
#if UNO_HAS_ENHANCED_LIFECYCLE
674+
_children;
675+
#else
676+
this.GetChildren();
677+
#endif
678+
679+
foreach (var child in children)
658680
{
659681
if (child == this)
660682
{
@@ -666,9 +688,14 @@ internal virtual void Leave(INameScope? nameScope, LeaveParams @params)
666688
continue;
667689
}
668690

691+
#if UNO_HAS_ENHANCED_LIFECYCLE
669692
child.Leave(nameScope, @params);
693+
#else
694+
(child as UIElement)?.Leave(nameScope, @params);
695+
#endif
670696
}
671697

698+
#if UNO_HAS_ENHANCED_LIFECYCLE
672699
if (IsActiveInVisualTree)
673700
{
674701
if (IsLoaded)
@@ -689,8 +716,7 @@ internal virtual void Leave(INameScope? nameScope, LeaveParams @params)
689716

690717
var eventManager = this.GetContext().EventManager;
691718
eventManager.RemoveRequest(this);
692-
}
693-
}
694719
#endif
720+
}
695721
}
696722
}

0 commit comments

Comments
 (0)