diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement_EffectiveViewport.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement_EffectiveViewport.cs index 6a25c9aed445..b67f8e4287cc 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement_EffectiveViewport.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml/Given_FrameworkElement_EffectiveViewport.cs @@ -1120,12 +1120,12 @@ public EVPTreeListener(FrameworkElement root, FrameworkElement leaf) _root = root; _leaf = leaf; - leaf.Loaded += ElementLoaded; + leaf.Loading += ElementLoading; } - private void ElementLoaded(object sender, RoutedEventArgs e) + private void ElementLoading(FrameworkElement sender, object args) { - _leaf.Loaded -= ElementLoaded; + _leaf.Loading -= ElementLoading; Subscribe(sender); @@ -1155,7 +1155,7 @@ public EVPListener Of() public void Dispose() { - _leaf.Loaded -= ElementLoaded; + _leaf.Loading -= ElementLoading; foreach (var listener in _listeners.Values) { listener.Dispose(); diff --git a/src/Uno.UI/UI/Xaml/FrameworkElement.EffectiveViewport.cs b/src/Uno.UI/UI/Xaml/FrameworkElement.EffectiveViewport.cs index 7c1d3ea0abf3..3e3b05f52349 100644 --- a/src/Uno.UI/UI/Xaml/FrameworkElement.EffectiveViewport.cs +++ b/src/Uno.UI/UI/Xaml/FrameworkElement.EffectiveViewport.cs @@ -33,6 +33,7 @@ partial class FrameworkElement : IFrameworkElement_EffectiveViewport { private static readonly RoutedEventHandler ReconfigureViewportPropagationOnLoad = (snd, e) => ((_This)snd).ReconfigureViewportPropagation(); private event TypedEventHandler<_This, EffectiveViewportChangedEventArgs>? _effectiveViewportChanged; + private bool _hasNewHandler; private int _childrenInterestedInViewportUpdates; private IDisposable? _parentViewportUpdatesSubscription; private ViewportInfo _parentViewport = ViewportInfo.Empty; // WARNING: Stored in parent's coordinates space, use GetParentViewport() @@ -45,6 +46,7 @@ public event TypedEventHandler<_This, EffectiveViewportChangedEventArgs> Effecti { add { + _hasNewHandler = true; _effectiveViewportChanged += value; ReconfigureViewportPropagation(isInternal: true); } @@ -321,8 +323,14 @@ private void PropagateEffectiveViewportChange( + $"| reason: {caller} " + $"| children: {_childrenInterestedInViewportUpdates}"); - if (!isInternal && viewportUpdated) // We don't want to raise the event when we are only initializing the tree due to a new event handler + if (viewportUpdated + && ( + !isInternal // We don't want to raise the event when we are only initializing the tree due to a new event handler somewhere in sub tree + || _hasNewHandler // but if we have a new local handler, we do need to raise the event! + )) { + _hasNewHandler = false; + // Note: The event only notify about the parentViewport (expressed in local coordinate space!), // the "local effective viewport" is used only by our children. _effectiveViewportChanged?.Invoke(this, new EffectiveViewportChangedEventArgs(parentViewport.Effective));