- Add icon.png for NuGet package - Add PackageIcon and PackageReadmeFile to csproj - Fix license from MIT to BSD-3-Clause (correct license per original) - Add Copyright notice crediting original author 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
8.5 KiB
MarketAlly.Mopups
Customizable popups for .NET MAUI with multi-window support. A fork of Mopups by Tyson Hooker (LuckyDucko) with enhanced multi-window capabilities for all platforms.
Table of Contents
- Features
- Installation
- Quick Start
- Multi-Window Support
- Usage
- Platform Support
- Requirements
- License
- Acknowledgments
Features
Core Capabilities (from Mopups)
- Customizable Popups: Full control over popup appearance and behavior
- Async/Await Pattern: Modern asynchronous popup handling
- Animation Support: Built-in appearing and disappearing animations
- System Padding: Automatic safe area handling
- Back Button Handling: Customizable back button behavior
- Cross-Platform: iOS, Android, Windows, and macOS (Mac Catalyst)
New in MarketAlly.Mopups v2.0.0
- Multi-Window Support: Display popups on specific windows instead of always on the main window
- Windows: Uses target window's
XamlRoot - iOS/iPadOS: Uses target window's
UIWindowScene - macOS Catalyst: Uses target window's
UIWindowScene - Android: Uses target window's Activity
DecorView
- Windows: Uses target window's
Installation
Install via NuGet Package Manager:
dotnet add package MarketAlly.Mopups
Or via Package Manager Console:
Install-Package MarketAlly.Mopups
Quick Start
1. Configure in MauiProgram.cs
using Mopups.Hosting;
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureMopups(); // Add this line
return builder.Build();
}
2. Create a Popup Page
using Mopups.Pages;
public class MyPopupPage : PopupPage
{
public MyPopupPage()
{
Content = new StackLayout
{
Children =
{
new Label { Text = "Hello from popup!" },
new Button { Text = "Close", Command = new Command(async () =>
await MopupService.Instance.PopAsync()) }
}
};
}
}
3. Show the Popup
using Mopups.Services;
// Show on main window (default behavior)
await MopupService.Instance.PushAsync(new MyPopupPage());
// Show on specific window (NEW in v2.0.0)
await MopupService.Instance.PushAsync(new MyPopupPage(), targetWindow);
Multi-Window Support
The key enhancement in MarketAlly.Mopups is the ability to display popups on specific windows. This is essential for applications with multiple windows, such as:
- Helper/tool windows
- Document windows
- Settings panels
- Floating utility windows
API
// Standard push (uses main window)
Task PushAsync(PopupPage page, bool animate = true);
// Window-aware push (NEW)
Task PushAsync(PopupPage page, Window? window, bool animate = true);
Example: Showing Dialog on Helper Window
public class HelperWindow : Window
{
public async Task ShowConfirmation()
{
var popup = new ConfirmationPopup();
// Pass 'this' to show popup on this window, not the main window
await MopupService.Instance.PushAsync(popup, this);
}
}
Platform Implementation Details
| Platform | How Window is Used |
|---|---|
| Windows | Gets XamlRoot from the target window's native Microsoft.UI.Xaml.Window |
| iOS/iPadOS | Gets UIWindowScene from the target window's native UIWindow |
| macOS Catalyst | Gets UIWindowScene from the target window's native UIWindow |
| Android | Gets DecorView from the target window's Activity |
Usage
Basic Popup Operations
// Push a popup
await MopupService.Instance.PushAsync(new MyPopupPage());
// Push with animation control
await MopupService.Instance.PushAsync(new MyPopupPage(), animate: false);
// Pop the topmost popup
await MopupService.Instance.PopAsync();
// Pop all popups
await MopupService.Instance.PopAllAsync();
// Remove specific popup
await MopupService.Instance.RemovePageAsync(specificPopup);
// Check popup stack
var popupStack = MopupService.Instance.PopupStack;
Events
MopupService.Instance.Pushing += (sender, args) =>
Console.WriteLine($"Pushing: {args.Page}");
MopupService.Instance.Pushed += (sender, args) =>
Console.WriteLine($"Pushed: {args.Page}");
MopupService.Instance.Popping += (sender, args) =>
Console.WriteLine($"Popping: {args.Page}");
MopupService.Instance.Popped += (sender, args) =>
Console.WriteLine($"Popped: {args.Page}");
PopupPage Properties
public class MyPopupPage : PopupPage
{
public MyPopupPage()
{
// Background click dismisses popup
CloseWhenBackgroundIsClicked = true;
// Handle safe areas
HasSystemPadding = true;
// Background color
BackgroundColor = Color.FromRgba("#80000000");
}
// Override for custom back button behavior
protected override bool OnBackButtonPressed()
{
// Return true to prevent dismissal
return false;
}
}
Platform Support
| Platform | Minimum Version | Multi-Window Support |
|---|---|---|
| iOS | 11.0 | Yes (iOS 13+ with UIScene) |
| Android | API 21 (5.0) | Yes (Android 7.0+ multi-window) |
| Windows | 10.0.17763.0 | Yes |
| macOS | 13.1 (Catalyst) | Yes |
Requirements
- .NET 9.0
- Microsoft.Maui.Controls 9.0+
- Microsoft.Maui.Essentials 9.0+
License
This project is licensed under the BSD 3-Clause License.
BSD 3-Clause License
Copyright (c) 2022, Tyson Elliot Hooker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Acknowledgments
This project is a fork of Mopups, originally created by Tyson Hooker (LuckyDucko). We extend our gratitude to:
- Tyson Hooker - Original author and maintainer of Mopups
- Maksym Koshovyi - Contributor
- Aswin P G - Contributor
- Kirill Lyubimov - Contributor
- Martijn Van Dijk - Contributor
- Shane Neuville - Contributor
Mopups itself was created as a replacement for the "Rg.Plugins.Popups" plugin for Xamarin, providing a modern popup solution for .NET MAUI.
Additional Resources
Built with precision by MarketAlly
Multi-window popup support for .NET MAUI applications.