feat: add LargeMessageBoxControl and improve MessageBox functionality

This commit is contained in:
2026-01-22 16:48:21 +08:00
parent 975757dbb8
commit c0a9852f9e
5 changed files with 319 additions and 18 deletions

View File

@@ -133,15 +133,22 @@ public class Marquee : ContentControl
private void TimerOnTick(object? sender, System.EventArgs e)
{
if (Presenter is null) return;
var layoutValues = Dispatcher.UIThread.Invoke(GetLayoutValues);
var location = UpdateLocation(layoutValues);
if (location is null) return;
Dispatcher.UIThread.Post(() =>
try
{
Canvas.SetTop(Presenter, location.Value.top);
Canvas.SetLeft(Presenter, location.Value.left);
}, DispatcherPriority.Render);
if (Presenter is null) return;
var layoutValues = Dispatcher.UIThread.Invoke(GetLayoutValues);
var location = UpdateLocation(layoutValues);
if (location is null) return;
Dispatcher.UIThread.Post(() =>
{
Canvas.SetTop(Presenter, location.Value.top);
Canvas.SetLeft(Presenter, location.Value.left);
}, DispatcherPriority.Render);
}
catch (Exception exception)
{
// pass
}
}
private void InvalidatePresenterPosition()
@@ -277,4 +284,4 @@ struct LayoutValues
public Direction Direction { get; set; }
public HorizontalAlignment HorizontalAlignment { get; set; }
public VerticalAlignment VerticalAlignment { get; set; }
}
}

View File

@@ -2,6 +2,8 @@ using Avalonia;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Styling;
using Ursa.Common;
namespace Ursa.Controls;
@@ -81,6 +83,7 @@ public static class MessageBox
MessageIcon = icon,
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
};
if (!string.IsNullOrWhiteSpace(styleClass))
{
var styles = styleClass!.Split(Constants.SpaceSeparator, StringSplitOptions.RemoveEmptyEntries);
@@ -90,4 +93,92 @@ public static class MessageBox
var result = await messageControl.ShowAsync<MessageBoxResult>();
return result;
}
}
public static async Task<MessageBoxResult> ShowLargeOverlayAsync(
string message,
string? title = null,
MessageBoxIcon icon = MessageBoxIcon.None,
MessageBoxButton button = MessageBoxButton.OK,
string yesString = "",
string noString = "",
string cancelString = "",
string okString = "")
{
var host = OverlayDialogManager.GetHost(null, null);
if (host is null) return MessageBoxResult.None;
var messageControl = new MessageBoxControl
{
Content = message,
Title = title,
Buttons = button,
MessageIcon = icon,
[KeyboardNavigation.TabNavigationProperty] = KeyboardNavigationMode.Cycle
};
if (Application.Current?.TryGetResource("LargeMessageBoxControl", ThemeVariant.Default, out var themeObj) == true
&& themeObj is ControlTheme theme)
{
messageControl.Theme = theme;
}
object? originalYes = null;
object? originalNo = null;
object? originalCancel = null;
object? originalOk = null;
var hadYes = false;
var hadNo = false;
var hadCancel = false;
var hadOk = false;
if (!string.IsNullOrEmpty(yesString))
{
hadYes = messageControl.Resources.TryGetValue("STRING_MENU_DIALOG_YES", out originalYes);
messageControl.Resources["STRING_MENU_DIALOG_YES"] = yesString;
}
if (!string.IsNullOrEmpty(noString))
{
hadNo = messageControl.Resources.TryGetValue("STRING_MENU_DIALOG_NO", out originalNo);
messageControl.Resources["STRING_MENU_DIALOG_NO"] = noString;
}
if (!string.IsNullOrEmpty(cancelString))
{
hadCancel = messageControl.Resources.TryGetValue("STRING_MENU_DIALOG_CANCEL", out originalCancel);
messageControl.Resources["STRING_MENU_DIALOG_CANCEL"] = cancelString;
}
if (!string.IsNullOrEmpty(okString))
{
hadOk = messageControl.Resources.TryGetValue("STRING_MENU_DIALOG_OK", out originalOk);
messageControl.Resources["STRING_MENU_DIALOG_OK"] = okString;
}
DialogControlBase.SetCanDragMove(messageControl, false);
host.AddModalDialog(messageControl);
try
{
var result = await messageControl.ShowAsync<MessageBoxResult>();
return result;
}
finally
{
if (!string.IsNullOrEmpty(yesString))
{
if (hadYes) messageControl.Resources["STRING_MENU_DIALOG_YES"] = originalYes!;
else messageControl.Resources.Remove("STRING_MENU_DIALOG_YES");
}
if (!string.IsNullOrEmpty(noString))
{
if (hadNo) messageControl.Resources["STRING_MENU_DIALOG_NO"] = originalNo!;
else messageControl.Resources.Remove("STRING_MENU_DIALOG_NO");
}
if (!string.IsNullOrEmpty(cancelString))
{
if (hadCancel) messageControl.Resources["STRING_MENU_DIALOG_CANCEL"] = originalCancel!;
else messageControl.Resources.Remove("STRING_MENU_DIALOG_CANCEL");
}
if (!string.IsNullOrEmpty(okString))
{
if (hadOk) messageControl.Resources["STRING_MENU_DIALOG_OK"] = originalOk!;
else messageControl.Resources.Remove("STRING_MENU_DIALOG_OK");
}
}
}
}

View File

@@ -104,8 +104,8 @@ public class MessageBoxControl : DialogControlBase
private void SetButtonVisibility()
{
var closeButtonVisible = Buttons != MessageBoxButton.YesNo;
IsVisibleProperty.SetValue(closeButtonVisible, _closeButton);
//var closeButtonVisible = Buttons != MessageBoxButton.YesNo;
IsVisibleProperty.SetValue(true, _closeButton);
switch (Buttons)
{
case MessageBoxButton.OK:
@@ -137,7 +137,7 @@ public class MessageBoxControl : DialogControlBase
{
MessageBoxButton.OK => MessageBoxResult.OK,
MessageBoxButton.OKCancel => MessageBoxResult.Cancel,
MessageBoxButton.YesNo => MessageBoxResult.No,
MessageBoxButton.YesNo => MessageBoxResult.Cancel,
MessageBoxButton.YesNoCancel => MessageBoxResult.Cancel,
_ => MessageBoxResult.None
};