Skip to content

Popup V2 #1581

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged

Conversation

bijington
Copy link
Contributor

@bijington bijington commented Nov 29, 2023

Description of Change

Popup v2 completely redesigns Popup from the ground up. Instead of using custom handlers to create a Popup, instead of using janky workarounds to display the popup, and instead of using janky workarounds to size + position the Popup, Popup now inherits from ContentView and is displayed using a Transparent Modal Page.

Under the hood, we've created internal class PopupPage : Content, a transparent ContentPage that is used to display content. When ShowPopupAsync() is called, we now use the MAUI's INavigation to display the Popup on a PopupPage using await Navigation.PushModalAsync(popupPage, shouldAnimate: false).

There are also now 2 ways user can create popup:

  • Create custom control inheriting from Popup
  • Pass in a View directly to ShowPopup
    • e.g. Shell.Current.ShowPopup(new Label { Text = "This is a Popup" })

For MVVM users there is a PopupService. Pay attention all popups must be registered. Also you can close popup from PopupService only if you opened it using PopupService. DO NOT combine extension method and PopupService.

Now all configurations live in PopupOptions. You can configure PageOverlayColor, Shadow, Border, BorderThickness, BorderStrokeThickness and CanBeClosedByTappingOutsidePopup.

The BindingContext is set automatically to PopupContainer, Popup and View.

As the new Popup uses only MAUI Controls, we expect you get all benefits of HotReload. All Controls including Popup in Popup and MediaElement should work without issues.

Features removed: AnchorView.

Linked Issues

PR Checklist

Migration Guide

Popup XAML/CS

  • Remove CanBeDismissedByTappingOutsideOfPopup and pass parameter using PopupOptions
  • Color is replaced with Background Color
  • Size is replaced with WidthRequest and HeightRequest

You can now use any View as Popup Content without inheriting it from Popup. But if you need to return a result from the popup, you have to inherit from Popup.

Popup Service

  • All popup configurations can be configured using PopupOptions and passed as a parameter
  • You need to pass INavigation to make sure the popup is displayed on the correct window.

@ne0rrmatrix
Copy link
Contributor

ne0rrmatrix commented Dec 1, 2023

I have ended up rewriting at least 3 or 4 samples submitted as bugs using standard DI pattern because the code would crash in IOS 17.x. I wanted to verify the issues that were being reported. If I see a bunch of different reports I put extra effort in.

Simplifying implementation would be great. I am all for that.

@bijington bijington added the needs discussion Discuss it on the next Monthly standup label Dec 5, 2023
@TheCodeTraveler TheCodeTraveler removed the needs discussion Discuss it on the next Monthly standup label Jan 4, 2024
@bijington
Copy link
Contributor Author

There are currently a couple of breaking changes to the IPopupService that I think are still good but we should consider documenting them to aid developers upgrading:

await popupService.ShowPopupAsync<MockPageViewModel>(CancellationToken.None);

becomes

await popupService.ShowPopupAsync<MockPageViewModel>(token: CancellationToken.None);
await Assert.ThrowsAsync<TaskCanceledException>(() => popupService.ShowPopupAsync<MockPageViewModel>(viewModel => viewModel.HasLoaded = true, cts.Token));

becomes

await Assert.ThrowsAsync<TaskCanceledException>(() => popupService.ShowPopupAsync<MockPageViewModel>(viewModel => viewModel.HasLoaded = true, token: cts.Token));

It also involves removing the ability to supply a viewModel instance to the Show methods to remove the confusion we have seen around developers expecting the BindingContext to automatically be set. I am happy to move this into a separate PR if we think it if worthwhile?

@bijington bijington marked this pull request as ready for review February 11, 2024 14:26
@TheCodeTraveler
Copy link
Collaborator

@bijington FYI - we now have a few merge conflicts on this PR after merging a bunch of Popup PRs today

@dotnet-policy-service dotnet-policy-service bot added stale The author has not responded in over 30 days help wanted This proposal has been approved and is ready to be implemented labels Apr 27, 2024
@bijington bijington removed help wanted This proposal has been approved and is ready to be implemented stale The author has not responded in over 30 days labels Jun 5, 2024
@bijington bijington requested a review from a team June 9, 2024 20:43
@bijington bijington changed the title Initial musings on showing popups without having to subclass Popup Provide the ability to show popups without having to subclass Popup Jun 20, 2024
@dotnet-policy-service dotnet-policy-service bot added stale The author has not responded in over 30 days help wanted This proposal has been approved and is ready to be implemented labels Jul 22, 2024
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 5 out of 11 changed files in this pull request and generated no suggestions.

Files not reviewed (6)
  • samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/MultiplePopupPage.xaml: Language not supported
  • samples/CommunityToolkit.Maui.Sample/Views/Popups/PopupContentView.xaml: Language not supported
  • samples/CommunityToolkit.Maui.Sample/MauiProgram.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/MultiplePopupViewModel.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/PopupContentViewModel.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/Views/Popups/PopupContentView.xaml.cs: Evaluated as low risk

@VladislavAntonyuk VladislavAntonyuk force-pushed the feature/sl/remove-popup-constraint-from-popup-service branch from c1488d0 to ebc39f2 Compare January 15, 2025 00:11
@VladislavAntonyuk VladislavAntonyuk self-assigned this Jan 15, 2025
@VladislavAntonyuk VladislavAntonyuk force-pushed the feature/sl/remove-popup-constraint-from-popup-service branch from aeb9020 to 94bee57 Compare January 15, 2025 18:52
Copy link
Member

@pictos pictos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job! I didn't run locally yet, just reviewed the code.

I saw that you removed the old popups reference, and I think we should mark them as obsolete and let them live for a while before removing everything. At least is what I remember from the last standup.

Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 81 out of 96 changed files in this pull request and generated no comments.

Files not reviewed (15)
  • samples/CommunityToolkit.Maui.Sample/App.xaml: Language not supported
  • samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/MultiplePopupPage.xaml: Language not supported
  • samples/CommunityToolkit.Maui.Sample/Resources/Styles/Styles.xaml: Language not supported
  • samples/CommunityToolkit.Maui.Sample/Models/PopupSize.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/AppShell.xaml.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/PopupSizingIssuesViewModel.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/StylePopupViewModel.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/PopupPositionViewModel.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/CustomSizeAndPositionPopupViewModel.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/UpdatingPopupViewModel.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/Pages/Views/MediaElement/MediaElementPage.xaml.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/PopupLayoutAlignmentPage.xaml.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/ShowPopupInOnAppearingPage.xaml.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/ViewsGalleryViewModel.cs: Evaluated as low risk
  • samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/PopupAnchorViewModel.cs: Evaluated as low risk
Comments suppressed due to low confidence (1)

samples/CommunityToolkit.Maui.Sample/ViewModels/Views/Popup/PopupContentViewModel.cs:8

  • The property name 'message' should be renamed to 'Message' to follow PascalCase convention.
string message = "";

@VladislavAntonyuk VladislavAntonyuk added pending documentation This feature requires documentation and removed help wanted This proposal has been approved and is ready to be implemented stale The author has not responded in over 30 days labels Jan 15, 2025
@bijington
Copy link
Contributor Author

This PR is also extremely close to merging. I'm working on the docs this week which is the final hurdle

@TheCodeTraveler TheCodeTraveler dismissed pictos’s stale review May 25, 2025 19:52

Handlers re-added with [Obsolete]. We will remove them in the .NET 10 PR.

@TheCodeTraveler TheCodeTraveler requested a review from Copilot May 25, 2025 20:41
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR refactors the popup samples to use the new IPopupService API (Popup V2), removes legacy popup pages, and updates popup configuration property names, service registrations, and styles for compatibility with MAUI Toolkit Popup V2.

  • Replace direct ShowPopupAsync extension and PopupSizeConstants usage with IPopupService injection across sample pages.
  • Remove obsolete sample pages (PopupAnchorPage, MultiplePopupPage, CustomSizeAndPositionPopupPage) and update navigation routes to the consolidated PopupsPage.
  • Update PopupOptions property names (e.g., WidthRequest, HeightRequest, BackgroundColor), bump package and MAUI versions, and refresh service registrations for new popups.

Reviewed Changes

Copilot reviewed 137 out of 137 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/ShowPopupInOnAppearingPage.xaml.cs Inject IPopupService, track single display with flag
samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/PopupsPage.xaml.cs Inject IPopupService, consolidate handlers into PopupsPage
samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/PopupSizingIssuesPage.xaml Rename title, remove obsolete CommandParameter binding
samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/PopupLayoutAlignmentPage.xaml.cs Update layout option logic; switch to ShowPopup call
samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/PopupOnDisappearingPage.cs Switch to inline ShowPopupAsync on disappearing
samples/CommunityToolkit.Maui.Sample/MauiProgram.cs Remove PopupSizeConstants, overhaul popup registrations
samples/CommunityToolkit.Maui.Sample/CommunityToolkit.Maui.Sample.csproj Bump toolkit and resilience package versions
samples/CommunityToolkit.Maui.Sample/AppShell.xaml.cs Update shell route mappings for new popup pages
samples/CommunityToolkit.Maui.Sample/App.xaml Migrate popup style setters to new property names
Directory.Build.props Bump MAUI package version and suppress new analyzer ID
Comments suppressed due to low confidence (3)

samples/CommunityToolkit.Maui.Sample/MauiProgram.cs:125

  • IPopupService is injected into several pages but not registered in the DI container. Add a registration like builder.Services.AddSingleton<IPopupService, PopupService>(); before consuming it.
builder.Services.AddSingleton<AppShell>();

samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/ShowPopupInOnAppearingPage.xaml.cs:9

  • [nitpick] Private fields should follow .NET conventions by being prefixed with an underscore. Consider renaming hasPopupBeenShown to _hasPopupBeenShown.
bool hasPopupBeenShown;

samples/CommunityToolkit.Maui.Sample/Pages/Views/Popup/PopupSizingIssuesPage.xaml:25

  • The CommandParameter binding was removed but ShowPopupCommand likely needs the page reference for anchoring the popup. If the view model still depends on a parameter, either restore the CommandParameter="{Binding Source={x:Reference Self}}" or update the command implementation to no longer require an argument.
<Button Text="Show Popup" Command="{Binding ShowPopupCommand}"/>

This ensures we do not forget to remove the Obsolete Popup classes in our .NET 10 release
* Add `Close()`

* Update PopupExtensions.shared.cs

* Add CancellationToken

* Add Unit Tests

* Add Support for Shell

* Add .NET 10 Compiler Error

This ensures we do not forget to remove the Obsolete Popup classes in our .NET 10 release

* Rename `Close()` -> `CloseAsync()`

* Add `[EditorBrowsable(EditorBrowsableState.Never)]` to Obsolete classes

* Update Samples

* Fix XML
@TheCodeTraveler
Copy link
Collaborator

Here are the updated Requirements we'll add to the next Release Notes:

Breaking Changes

  • Popup.Anchor feature removed

Requirements

The following tools are now required for CommunityToolkit.Maui:

  • Download/install .NET SDK v9.0.300
  • Install Xcode 16.2.0 (or higher)
    • Read the latest .NET MAUI Release wiki to always find the latest-supported version) of Xcode for .NET MAUI
    • We HIGHLY recommend using the open-source tool Xcodes to easily manage your installed Xcode versions
  • Update to the latest stable version of Visual Studio (or Jet Brains Rider)
  • After installing the latest stable .NET SDK, update to the latest stable version of the .NET MAUI workload:
    • On macOS, open the Terminal and enter the following command: sudo dotnet workload install maui; sudo dotnet workload update
    • On Windows, open the command prompt (or Powershell) and enter the following command: dotnet workload install maui & dotnet workload update
  • Add a global.json file to your application with the following parameters to ensure you're not using a unsupported preview version of .NET (example below)
    • The .NET MAUI Community Toolkit does not support preview releases of .NET

global.json

{
  "sdk": {
    "version": "9.0.300", 
    "rollForward": "latestFeature",
    "allowPrerelease": false
  }
}

@TheCodeTraveler TheCodeTraveler merged commit 0bc2572 into main May 26, 2025
8 of 10 checks passed
@TheCodeTraveler TheCodeTraveler deleted the feature/sl/remove-popup-constraint-from-popup-service branch May 26, 2025 22:23
@github-actions github-actions bot locked and limited conversation to collaborators May 28, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
approved This Proposal has been approved and is ready to be added to the Toolkit area/views Issue/Discussion/PR that has to do with Views breaking change This label is used for PRs that include a breaking change pending documentation This feature requires documentation
Projects
None yet
8 participants