Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ public partial class VisualElement
{
partial void HandlePlatformUnloadedLoaded()
{
if (Window != null)
if (this.IsLoaded)
{
SendLoaded();
SendLoaded(false);
}
else
{
SendUnloaded();
SendUnloaded(false);
}
}
}
Expand Down
20 changes: 11 additions & 9 deletions src/Controls/src/Core/VisualElement/VisualElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2146,19 +2146,19 @@ public event EventHandler? Loaded
{
add
{
bool watchingLoaded = _watchingPlatformLoaded;
bool loadedAlreadyFired = _isLoadedFired;

_loaded += value;
UpdatePlatformUnloadedLoadedWiring(Window);

// The point of this code, is to fire loaded if the element is already loaded.
//
// If this is the first time the user is subscribing to Loaded,
// UpdatePlatformUnloadedLoadedWiring will take care of firing Loaded.
// If we are already wired up to watch loaded, then we'll fire it off if we know this
// view is in a state where it's been determined that it's accurate to fire
// _isLoadedFired.
if (_isLoadedFired && watchingLoaded)
// The first time UpdatePlatformUnloadedLoadedWiring is called it will handle
// invoking _loaded
// This is only to make sure that new subscribers get invoked when the element is already loaded
// and a previous subscriber has already invoked the UpdatePlatformUnloadedLoadedWiring path
if (loadedAlreadyFired && _isLoadedFired)
{
value?.Invoke(this, EventArgs.Empty);
}

}
remove
Expand Down Expand Up @@ -2212,7 +2212,9 @@ void SendLoaded(bool updateWiring)
// unloaded is still correctly being watched for.

if (updateWiring)
{
UpdatePlatformUnloadedLoadedWiring(Window);
}
}

void SendUnloaded() => SendUnloaded(true);
Expand Down
40 changes: 35 additions & 5 deletions src/Controls/tests/Core.UnitTests/PageLifeCycleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,31 @@ public async Task LoadedUnLoadedEvents()
Assert.Equal(1, unLoadedCnt);
}

[Fact]
public async Task LoadedFiresOnSecondSubscription()
{
var previousPage = new LCPage();
var lcPage = new LCPage();
var navigationPage =
new TestNavigationPage(true, previousPage)
.AddToTestWindow();

await navigationPage.PushAsync(lcPage);

int loadedCnt = 0;
lcPage.Loaded += OnLoaded;
Assert.Equal(1, loadedCnt);

lcPage.Loaded -= OnLoaded;
lcPage.Loaded += OnLoaded;
Assert.Equal(2, loadedCnt);

void OnLoaded(object sender, System.EventArgs e)
{
loadedCnt++;
}
}

[Fact]
public async Task LoadedFiresOnInitialSubscription()
{
Expand All @@ -299,6 +324,7 @@ public async Task LoadedFiresOnInitialSubscription()
await navigationPage.PushAsync(lcPage);

int loadedCnt = 0;
int secondLoadedSubscriberCnt = 0;
int unLoadedCnt = 0;

Assert.True(lcPage.IsLoaded);
Expand All @@ -309,21 +335,25 @@ public async Task LoadedFiresOnInitialSubscription()
loadedCnt++;
};

// Subscribing to loaded should fire the loaded
// event if the page is already loaded
Assert.Equal(1, loadedCnt);

// Subscribing to loaded a second time
// Should fire the event on the new subsciber;
lcPage.Loaded += (_, _) =>
{
loadedCnt++;
secondLoadedSubscriberCnt++;
};

lcPage.Unloaded += (_, _) => unLoadedCnt++;

Assert.Equal(2, loadedCnt);
Assert.Equal(1, loadedCnt);
Assert.Equal(1, secondLoadedSubscriberCnt);
Assert.Equal(0, unLoadedCnt);

await navigationPage.PopAsync();

Assert.Equal(2, loadedCnt);
Assert.Equal(1, loadedCnt);
Assert.Equal(1, secondLoadedSubscriberCnt);
Assert.Equal(1, unLoadedCnt);
}

Expand Down