using Avalonia; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using DataLayer; using LibationWinForms.AvaloniaUI.ViewModels.Dialogs; using LibationWinForms.AvaloniaUI.Views.Dialogs; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace LibationWinForms.AvaloniaUI { public enum DialogResult { None = 0, OK = 1, Cancel = 2, Abort = 3, Retry = 4, Ignore = 5, Yes = 6, No = 7, TryAgain = 10, Continue = 11 } public enum MessageBoxIcon { None = 0, Error = 16, Hand = 16, Stop = 16, Question = 32, Exclamation = 48, Warning = 48, Asterisk = 64, Information = 64 } public enum MessageBoxButtons { OK, OKCancel, AbortRetryIgnore, YesNoCancel, YesNo, RetryCancel, CancelTryContinue } public enum MessageBoxDefaultButton { Button1, Button2 = 256, Button3 = 512, } public class MessageBox { /// Displays a message box with the specified text, caption, buttons, icon, and default button. /// The text to display in the message box. /// The text to display in the title bar of the message box. /// One of the values that specifies which buttons to display in the message box. /// One of the values that specifies which icon to display in the message box. /// One of the values that specifies the default button for the message box. /// One of the values. /// /// is not a member of . /// -or- /// is not a member of . /// -or- /// is not a member of . /// An attempt was made to display the in a process that is not running in User Interactive mode. This is specified by the property. public static async Task Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton) { return await ShowCore(null, text, caption, buttons, icon, defaultButton); } /// Displays a message box with specified text, caption, buttons, and icon. /// The text to display in the message box. /// The text to display in the title bar of the message box. /// One of the values that specifies which buttons to display in the message box. /// One of the values that specifies which icon to display in the message box. /// One of the values. /// The parameter specified is not a member of . /// -or- /// The parameter specified is not a member of . /// An attempt was made to display the in a process that is not running in User Interactive mode. This is specified by the property. public static async Task Show(string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon) { return await ShowCore(null, text, caption, buttons, icon, MessageBoxDefaultButton.Button1); } /// Displays a message box with specified text, caption, and buttons. /// The text to display in the message box. /// The text to display in the title bar of the message box. /// One of the values that specifies which buttons to display in the message box. /// One of the values. /// The parameter specified is not a member of . /// An attempt was made to display the in a process that is not running in User Interactive mode. This is specified by the property. public static async Task Show(string text, string caption, MessageBoxButtons buttons) { return await ShowCore(null, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1); } /// Displays a message box with specified text and caption. /// The text to display in the message box. /// The text to display in the title bar of the message box. /// One of the values. public static async Task Show(string text, string caption) { return await ShowCore(null, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1); } /// Displays a message box with specified text. /// The text to display in the message box. /// One of the values. public static async Task Show(string text) { return await ShowCore(null, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1); } /// Displays a message box in front of the specified object and with the specified text, caption, buttons, icon, default button, and options. /// An implementation of that will own the modal dialog box. /// The text to display in the message box. /// The text to display in the title bar of the message box. /// One of the values that specifies which buttons to display in the message box. /// One of the values that specifies which icon to display in the message box. /// One of the values the specifies the default button for the message box. /// One of the values that specifies which display and association options will be used for the message box. You may pass in 0 if you wish to use the defaults. /// One of the values. /// /// is not a member of . /// -or- /// is not a member of . /// -or- /// is not a member of . /// An attempt was made to display the in a process that is not running in User Interactive mode. This is specified by the property. /// /// -or- /// specified an invalid combination of . public static async Task Show(Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton) { return await ShowCore(owner, text, caption, buttons, icon, defaultButton); } /// Displays a message box in front of the specified object and with the specified text, caption, buttons, and icon. /// An implementation of that will own the modal dialog box. /// The text to display in the message box. /// The text to display in the title bar of the message box. /// One of the values that specifies which buttons to display in the message box. /// One of the values that specifies which icon to display in the message box. /// One of the values. /// /// is not a member of . /// -or- /// is not a member of . /// An attempt was made to display the in a process that is not running in User Interactive mode. This is specified by the property. public static async Task Show(Window owner, string text, string caption, MessageBoxButtons buttons, MessageBoxIcon icon) { return await ShowCore(owner, text, caption, buttons, icon, MessageBoxDefaultButton.Button1); } /// Displays a message box in front of the specified object and with the specified text, caption, and buttons. /// An implementation of that will own the modal dialog box. /// The text to display in the message box. /// The text to display in the title bar of the message box. /// One of the values that specifies which buttons to display in the message box. /// One of the values. /// /// is not a member of . /// An attempt was made to display the in a process that is not running in User Interactive mode. This is specified by the property. public static async Task Show(Window owner, string text, string caption, MessageBoxButtons buttons) { return await ShowCore(owner, text, caption, buttons, MessageBoxIcon.None, MessageBoxDefaultButton.Button1); } /// Displays a message box in front of the specified object and with the specified text and caption. /// An implementation of that will own the modal dialog box. /// The text to display in the message box. /// The text to display in the title bar of the message box. /// One of the values. public static async Task Show(Window owner, string text, string caption) { return await ShowCore(owner, text, caption, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1); } /// Displays a message box in front of the specified object and with the specified text. /// An implementation of that will own the modal dialog box. /// The text to display in the message box. /// One of the values. public static async Task Show(Window owner, string text) { return await ShowCore(owner, text, string.Empty, MessageBoxButtons.OK, MessageBoxIcon.None, MessageBoxDefaultButton.Button1); } public static async Task ShowConfirmationDialog(Window owner, IEnumerable libraryBooks, string format, string title, MessageBoxDefaultButton defaultButton = MessageBoxDefaultButton.Button1) { if (libraryBooks is null || !libraryBooks.Any()) return DialogResult.Cancel; var count = libraryBooks.Count(); string thisThese = count > 1 ? "these" : "this"; string bookBooks = count > 1 ? "books" : "book"; string titlesAgg = libraryBooks.AggregateTitles(); var message = string.Format(format, $"{thisThese} {count} {bookBooks}") + $"\r\n\r\n{titlesAgg}"; return await ShowCore(owner, message, title, MessageBoxButtons.YesNo, MessageBoxIcon.Question, defaultButton); } private static async Task ShowCore(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton) { if (Avalonia.Threading.Dispatcher.UIThread.CheckAccess()) return await ShowCore2(owner, message, caption, buttons, icon, defaultButton); else return await Avalonia.Threading.Dispatcher.UIThread.InvokeAsync(() => ShowCore2(owner, message, caption, buttons, icon, defaultButton)); } private static async Task ShowCore2(Window owner, string message, string caption, MessageBoxButtons buttons, MessageBoxIcon icon, MessageBoxDefaultButton defaultButton) { var dialog = new MessageBoxWindow(); dialog.HideMinMaxBtns(); var vm = new MessageBoxViewModel(message, caption, buttons, icon, defaultButton); dialog.DataContext = vm; dialog.ControlToFocusOnShow = dialog.FindControl(defaultButton.ToString()); dialog.CanResize = false; dialog.WindowStartupLocation = WindowStartupLocation.CenterOwner; var tbx = dialog.FindControl("messageTextBlock"); tbx.MinWidth = vm.TextBlockMinWidth; tbx.Text = message; var thisScreen = (owner ?? dialog).Screens.ScreenFromVisual(owner ?? dialog); var maxSize = new Size(0.20 * thisScreen.Bounds.Width, 0.9 * thisScreen.Bounds.Height - 55); var desiredMax = new Size(maxSize.Width, maxSize.Height); tbx.Measure(desiredMax); tbx.Height = tbx.DesiredSize.Height; tbx.Width = tbx.DesiredSize.Width; dialog.MinHeight = vm.FormHeightFromTboxHeight((int)tbx.DesiredSize.Height); dialog.MinWidth = vm.FormWidthFromTboxWidth((int)tbx.DesiredSize.Width); dialog.MaxHeight = dialog.MinHeight; dialog.MaxWidth = dialog.MinWidth; dialog.Height = dialog.MinHeight; dialog.Width = dialog.MinWidth; if (owner is null) { if (Application.Current.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) { return await dialog.ShowDialog(desktop.MainWindow); } else { var window = new Window { IsVisible = false, Height = 1, Width = 1, SystemDecorations = SystemDecorations.None, ShowInTaskbar = false }; window.Show(); var result = await dialog.ShowDialog(window); window.Close(); return result; } } else { return await dialog.ShowDialog(owner); } } } }