Native MessageBox API
It would be great to have a native Message box API. Win32 on Windows and GTK on Linux / OSX (or Cocoa). Because Cocoa would need to probably be used on iOS anyway, it makes sense for OSX.
I think we should take inspiration from UWP and implement MessageDialog and ContentDialog
+1 for @nc4rrillo
will require #624 to also be completed.
I know it's a workaround but what about this: https://habr.com/en/post/454386/
Hi @danwalmsley ,
I see that https://github.com/AvaloniaUI/Avalonia/issues/624 was closed... Is this workable now?
Thanks, Kevin
Definitely possible now
Given that this issue is about native message boxes, I've done a bit of research into the various native message box APIs in the platforms we support:
Native Message Boxes
Win32
MessageBox
MessageBox shows a simple message box. It has the following elements:
- A title
- A text message
- A fixed choice of buttons (localized):
- OK
- OK, Cancel
- Yes, No
- Yes, No, Cancel
- Abort, Retry, Ignore
- Cancel, Try Again, Continue
- An optional Help button an be added to each of the above
- An icon:
- Exclamation,
- Warning
- Information/Asterisk
- Question
- Stop/Error/Hand
This is the API used by WPF's MessageBox.
TaskDialog
TaskDialog shows a "vista"-style messagebox. It has the following elements:
- A title
- A message ("main instruction")d
- Content (additional text that appears below the main instruction, in a smaller font)
- Any combination of buttons (localized):
- OK
- Yes
- No
- Cancel
- Retry
- Close
- An icon:
- Error
- Information
- Shield
- Warning
There is a proposal to add an API for this to WinForms: https://github.com/dotnet/winforms/issues/146
TaskDialogIndirect
TaskDialogIndirect shows an advanced "vista"-style messagebox. It has the elements from TaskDialog plus:
- A set of buttons that can be:
- Radio buttons
- Command links
- A verification checkbox
- An expander to show additional information
- An arbirary footer icon
- A footer message
- Hyperlinks in the content/expander/footer
- A progress bar
OSX
NSAlert shows a message box. It has the following elements:
- A message
- Informative text
- A type
- Critical
- Informational/Warning
- A custom icon
- An optional help button
- Arbitrary buttons
- A supression checkbox
- An accessory view containing arbitrary content
X11
On X11 message boxes are provided by the toolkit so we would have to implement our own managed message boxes, but for context here's what GTK and QT's message box APIs provide.
GTK
gtk_message_dialog_new is simply a convenince function for creating simple dialogs. It can be modified arbirarily, but the base API has the following elements:
- A title
- A message
- Secondary text
- An icon
- Information
- Warning
- Question
- Error
- Other (No icon)
- Buttons:
- OK (discouraged)
- Close
- Cancel
- Yes, No (discouraged)
- OK, Cancel (discouraged)
QT
QMessageBox shows a message box. It has the following elements:
- Primary text (plain or rich)
- Informative text (plain or rich)
- Optional detailed text
- An icon
- Question
- Information
- Warning
- Critical
- A custom bitmap
- Buttons:
- OK
- Open
- Save
- Cancel
- Close
- Discard
- Apply
- Reset
- RestoreDefaults
- Help
- Save All
- Yes
- Yes to All
- No
- No to All
- Abort
- Retry
- Ignore
Two APIs for using QMessageBox are provided, the property-based API, and the static functions. Calling one of the static functions is the simpler approach, but it is less flexible than using the property-based API, and the result is less informative. Using the property-based API is recommended.
Android
AlertDialog shows a message box. It has the following elements:
- Title
- Content area (can be text, a list or other custom layout)
- Up to 3 buttons with arbitrary text
iOS
UIAlertController shows a message box. It has the following elements:
- A title
- A message
- A style
- Action sheet (lays out actions vertically)
- Alert
- Arbitrary actions (buttons)
If we were to implement a native MessageBox API, I can see 3 choices:
- Implement a common subset. This would appear to be:
- Title (implemented on all platforms except OSX - could just not display it there)
- Message in plain text
- Win32
MessageBoxbutton choices if we use that API, or a arbitrary buttons if we useTaskDialog- Does
TaskDialoglook out of place in Win10? Does that matter?
- Does
- "Content" text could be displayed using the relevant feature on platforms that support it, and appended to the message on platforms that don't?
- This would essentially be WPF's
MessageBoxAPI (perhaps with added "content" text)
- Have some sort of capabilities query
- Would somewhat overcomplicate just showing a message box in a cross-platform manner
- Just provide the bare minimum somewhat like JS:
alertdisplays a message and an OK buttonconfirmdisplays a mesage and OK, Cancel buttons
Other things to note:
MessageBoxautomatically localizes the button text, which it can do because it has a limited set to choose from- Different platforms order the buttons differently (https://www.nngroup.com/articles/ok-cancel-or-cancel-ok/)
- win32's
MessageBoxat least blocks the main thread, which might cause problems
Note that we need some kind of localized text database anyway since we have default context menus textboxes.
Discussion about a new TaskDialog API in WinUI: https://github.com/microsoft/microsoft-ui-xaml/issues/2313 - though this is only really a "native" MessageBox in the sense that MS would be shipping it.
In terms of UI thread lock, I just worked around this issue in WPF with this simple function.
Can now run sync UI methods in a fully asynchronous way and await!
/// <summary>
/// Runs a synchronous action asynchronously on the UI thread.
/// </summary>
/// <param name="window">Any window to get the dispatcher from.</param>
/// <param name="action">The action to run asynchronously.</param>
/// <typeparam name="T">The return type of the action.</typeparam>
/// <returns>The result of the action.</returns>
public static Task<T> RunUiAsync<T>(this Window window, Func<T> action)
{
if (window == null) throw new ArgumentNullException(nameof(window));
TaskCompletionSource<T> completion = new();
window.Dispatcher.BeginInvoke(new Action(() => completion.SetResult(action())));
return completion.Task;
}
In the Avalonia port of MvvmDialogs, I need to have a common MessageBox API to share between WPF, Avalonia, UWP, WinUI3, Blazor or anything else (because the ViewModel shouldn't need to know which UI it's running on)
What we first need is a basic MessageBox with standard features which should be simple enough to implement.
Later on, you could add an ExtendedMessageBox in Avalonia with extra features, which will take more time and it will be harder to come with a stable cross-platform API for.
ExtendedMessageBox extension could later be added to MvvmDialogs with support for WPF/Ookii, and for Avalonia if that's added. But it's really difficult for these extended feature settings to be platform-agnostic.
My vote is that extended features do not need to be part of the core library but can be added through a separate project, but basic MessageBox features DO need to be part of the core library.
Here are the platform-agnostic settings implemented in MvvmDialogs.
Is there some issue in natively supporting those settings on all platforms? These basic settings cover 90% of use-cases.
NEED this
NEED this
@Anequit, while we wait for integration of this feature, have you checked out Prism.Avalonia? It offers seamless features with Dialog Services
NEED this
@Anequit, while we wait for integration of this feature, have you checked out MessageBox.Avalonia?
Yes I have, but I'm not a huge fan of it personally. I think for the time being I'll opt for an alert popup instead of a message box
have you checked out MessageBox.Avalonia?
I've just gave it a spin, and it's not resizing vertically for a long texts: https://github.com/AvaloniaCommunity/MessageBox.Avalonia/issues/104
It also has no API docs for MessageBoxStandardParams etc., looks like something unpolished / buggy to me =\
Would be happy to see out-of-the-box platform-agnostic solution in Avalonia.
Yes it has a lot of unpolished rough edges. It had no option for setting a default button; they added it but the implementation is badly designed and looks more like a hack.
I'm having a nice laugh finding out a few hours into coding that I basically have to write my own custom message box to give the user feedback. Incredible.
As an option, with Prism.Avalonia you make use of the DialogService which provides the ability to make it modal and non-modal with ease. It's pretty much 60 seconds of copy/paste as per the end-to-end sample
or using MvvmDialogs for Avalonia
Simple MessageBox should be higher on the implementation priority list. Cross Platform UI framework without a MessageBox!!
This is very necessary and without it it is very inconvenient to develop software!!! I wonder why this feature is still not available natively under Avalonia?
Agreed. This feels like a weird omission. MessageBoxes are not uncommon.
Agreed. This feels like a weird omission. MessageBoxes are not uncommon.
At the very least, a mechanism for basic error/alert notification with basic functionality should be considered.
Something that could rely on native implementations like message boxes or toasts.... or fallback to in built popups.
But it's a pain to go through hoops whenever a command execution throws an expected exception
The reason message boxes are nice is if you're trying to show something when the UI fails to render.
However for portability reasons, its best practice imo to actually just have a MessageBox overlay. This allows any OS or environment to render messages even when it doesn't support it. Like on console systems or maybe some other mobile platform. You can make a custom one of course pretty easy but having a message overlay system built in wouldn't be bad either.
Please see my implementation at https://github.com/CastelloBrancoTecnologia/AvaloniaMessageBox
If it will be usefull I will open an pr to you
Please see my implementation at https://github.com/CastelloBrancoTecnologia/AvaloniaMessageBox
If it will be usefull I will open an pr to you
You should consider adding Native-Platform Message Boxes. So for Android, iOS, Win32 , SDL for Linux etc. That way if the app has an unhandled exception and the app can't display anything, you can at least notify the user with a system dialog.
I think there's two completely separate tasks here, and IMHO, I beleve both should go in separate libraries.
Native message boxes are meant to display notifications, warnings and errors, nothing more, nothing less, and as @zezba9000 mentioned, by being native they may be able to show up in cases in which Avalonia may not be responsive.
Looking around, I found this c++ library attemptying exactly this: https://github.com/thegabman/native_message_box
General purpose dialog boxes are a completely different thing meant for presenting forms or other media content to the user.
Please see my implementation at https://github.com/CastelloBrancoTecnologia/AvaloniaMessageBox If it will be usefull I will open an pr to you
You should consider adding Native-Platform Message Boxes. So for Android, iOS, Win32 , SDL for Linux etc. That way if the app has an unhandled exception and the app can't display anything, you can at least notify the user with a
my messabox works before avalonia is avaliable, ie before mainwindow is created on app.cs framework initialization complete.
The only things it not works is in program.cs before avalonia builder has worked.
Also are there any way to detect if avalonia isn't avaliable? If Yes i can put an fallback to native os messagebox in my code.