Avalonia icon indicating copy to clipboard operation
Avalonia copied to clipboard

Native MessageBox API

Open zezba9000 opened this issue 9 years ago • 52 comments

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.

zezba9000 avatar Aug 06 '16 22:08 zezba9000

I think we should take inspiration from UWP and implement MessageDialog and ContentDialog

ncarrillo avatar Aug 07 '16 00:08 ncarrillo

+1 for @nc4rrillo

danwalmsley avatar Aug 07 '16 09:08 danwalmsley

will require #624 to also be completed.

danwalmsley avatar Aug 07 '16 09:08 danwalmsley

I know it's a workaround but what about this: https://habr.com/en/post/454386/

TherionIM avatar Jun 04 '19 05:06 TherionIM

Hi @danwalmsley ,

I see that https://github.com/AvaloniaUI/Avalonia/issues/624 was closed... Is this workable now?

Thanks, Kevin

KevinEady avatar Aug 03 '20 21:08 KevinEady

Definitely possible now

danwalmsley avatar Aug 03 '20 22:08 danwalmsley

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)

grokys avatar Jan 26 '21 21:01 grokys

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 MessageBox button choices if we use that API, or a arbitrary buttons if we use TaskDialog
      • Does TaskDialog look out of place in Win10? Does that matter?
    • "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 MessageBox API (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:
    • alert displays a message and an OK button
    • confirm displays a mesage and OK, Cancel buttons

Other things to note:

  • MessageBox automatically 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 MessageBox at least blocks the main thread, which might cause problems

grokys avatar Jan 26 '21 21:01 grokys

Note that we need some kind of localized text database anyway since we have default context menus textboxes.

kekekeks avatar Jan 26 '21 21:01 kekekeks

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.

grokys avatar Jan 26 '21 21:01 grokys

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;
}

mysteryx93 avatar Dec 12 '21 07:12 mysteryx93

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.

mysteryx93 avatar Dec 12 '21 16:12 mysteryx93

NEED this

Anequit avatar Feb 02 '22 15:02 Anequit

NEED this

@Anequit, while we wait for integration of this feature, have you checked out Prism.Avalonia? It offers seamless features with Dialog Services

DamianSuess avatar Feb 02 '22 19:02 DamianSuess

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

Anequit avatar Feb 02 '22 19:02 Anequit

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.

DmitriyYukhanov avatar Apr 01 '22 09:04 DmitriyYukhanov

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.

mysteryx93 avatar Apr 01 '22 19:04 mysteryx93

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.

jsreynolds avatar Sep 04 '24 21:09 jsreynolds

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

DamianSuess avatar Sep 04 '24 21:09 DamianSuess

or using MvvmDialogs for Avalonia

mysteryx93 avatar Sep 04 '24 21:09 mysteryx93

Simple MessageBox should be higher on the implementation priority list. Cross Platform UI framework without a MessageBox!!

kelvin-martin avatar Dec 22 '24 18:12 kelvin-martin

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?

sb-viktor avatar Feb 27 '25 07:02 sb-viktor

Agreed. This feels like a weird omission. MessageBoxes are not uncommon.

CriticalFlaw avatar Mar 29 '25 16:03 CriticalFlaw

Agreed. This feels like a weird omission. MessageBoxes are not uncommon.

CriticalFlaw avatar Mar 29 '25 16:03 CriticalFlaw

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

vpenades avatar Mar 31 '25 11:03 vpenades

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.

zezba9000 avatar Apr 02 '25 05:04 zezba9000

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.

zezba9000 avatar Apr 16 '25 19:04 zezba9000

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.

vpenades avatar Apr 16 '25 20:04 vpenades

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.