|
28 | 28 | using Uno.UI.Xaml.Controls;
|
29 | 29 | using Uno.UI.Xaml.Core;
|
30 | 30 | using Uno.UI.Xaml.Media;
|
| 31 | +using Microsoft.UI.Xaml.Markup; |
| 32 | + |
31 | 33 |
|
32 | 34 | #if __ANDROID__
|
33 | 35 | using View = Android.Views.View;
|
@@ -941,6 +943,67 @@ internal virtual void UpdateThemeBindings(ResourceUpdateReason updateReason)
|
941 | 943 | }
|
942 | 944 | }
|
943 | 945 |
|
| 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 | + |
944 | 1007 | #region AutomationPeer
|
945 | 1008 | #if !__IOS__ && !__ANDROID__ && !__MACOS__ // This code is generated in FrameworkElementMixins
|
946 | 1009 | private AutomationPeer _automationPeer;
|
|
0 commit comments