From 9d673fc0ded576a5c94d26c8932abbc996105f18 Mon Sep 17 00:00:00 2001 From: NotYoojun Date: Tue, 26 Dec 2023 11:54:43 +0800 Subject: [PATCH] Fix messagebox backdrop in dark mode & add sound --- .../Controls/MessageBox/MessageBox.Helper.cs | 24 +++++++----- .../Controls/MessageBox/MessageBox.cs | 39 +++++++++++++++++++ .../MessageBox/MessageBoxImageExtensions.cs | 20 +++++++++- source/samples/WpfApp1/MainWindow.xaml | 2 +- source/samples/WpfApp1/MainWindow.xaml.cs | 6 +-- 5 files changed, 76 insertions(+), 15 deletions(-) diff --git a/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBox.Helper.cs b/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBox.Helper.cs index 50d9e819..af06298c 100644 --- a/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBox.Helper.cs +++ b/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBox.Helper.cs @@ -3,6 +3,7 @@ using iNKORE.UI.WPF.Modern.Extensions; using System; using System.Linq; +using System.Media; using System.Threading.Tasks; using System.Windows; @@ -203,7 +204,7 @@ public static MessageBoxResult Show(Window owner, string messageBoxText, string /// A value that specifies which message box button is clicked by the user. /// By default, the message box appears in front of the window that is currently active. public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult? defaultResult) => - Show(owner, messageBoxText, caption, button, icon.ToSymbol(), defaultResult); + Show(owner, messageBoxText, caption, button, icon.ToSymbol(), defaultResult, icon.ToAlertSound()); /// /// Displays a message box in front of the specified window. The message box displays a message, title bar caption, button, and icon; and accepts a default message box result and returns a result. @@ -216,8 +217,8 @@ public static MessageBoxResult Show(Window owner, string messageBoxText, string /// A value that specifies the default result of the message box. /// A value that specifies which message box button is clicked by the user. /// By default, the message box appears in front of the window that is currently active. - public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, string icon, MessageBoxResult? defaultResult) => - Show(owner, messageBoxText, caption, button, new FontIconSource { Glyph = icon, FontSize = 30 }, defaultResult); + public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, string icon, MessageBoxResult? defaultResult, SystemSound sound = null) => + Show(owner, messageBoxText, caption, button, new FontIconSource { Glyph = icon, FontSize = 30 }, defaultResult, sound); /// /// Displays a message box in front of the specified window. The message box displays a message, title bar caption, button, and icon; and accepts a default message box result and returns a result. @@ -230,7 +231,7 @@ public static MessageBoxResult Show(Window owner, string messageBoxText, string /// A value that specifies the default result of the message box. /// A value that specifies which message box button is clicked by the user. /// By default, the message box appears in front of the window that is currently active. - public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, IconSource icon, MessageBoxResult? defaultResult) + public static MessageBoxResult Show(Window owner, string messageBoxText, string caption, MessageBoxButton button, IconSource icon, MessageBoxResult? defaultResult, SystemSound? sound = null) { if (owner is null) { @@ -248,6 +249,11 @@ public static MessageBoxResult Show(Window owner, string messageBoxText, string WindowStartupLocation = owner is null ? WindowStartupLocation.CenterScreen : WindowStartupLocation.CenterOwner }; + if (MakeSound) + { + window.SystemSoundOnLoaded = sound; + } + return window.ShowDialog(); } @@ -447,7 +453,7 @@ public static Task ShowAsync(Window owner, string messageBoxTe /// An asynchronous operation showing the message box. When complete, returns a . /// By default, the message box appears in front of the window that is currently active. public static Task ShowAsync(Window owner, string messageBoxText, string caption, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult? defaultResult) => - ShowAsync(owner, messageBoxText, caption, button, icon.ToSymbol(), defaultResult); + ShowAsync(owner, messageBoxText, caption, button, icon.ToSymbol(), defaultResult, icon.ToAlertSound()); /// /// Begins an asynchronous operation to displays a message box in front of the specified window. The message box displays a message, title bar caption, button, and icon; and accepts a default message box result and returns a result. @@ -460,8 +466,8 @@ public static Task ShowAsync(Window owner, string messageBoxTe /// A value that specifies the default result of the message box. /// An asynchronous operation showing the message box. When complete, returns a . /// By default, the message box appears in front of the window that is currently active. - public static Task ShowAsync(Window owner, string messageBoxText, string caption, MessageBoxButton button, string icon, MessageBoxResult? defaultResult) => - ShowAsync(owner, messageBoxText, caption, button, new FontIconSource { Glyph = icon, FontSize = 30 }, defaultResult); + public static Task ShowAsync(Window owner, string messageBoxText, string caption, MessageBoxButton button, string icon, MessageBoxResult? defaultResult, SystemSound sound = null) => + ShowAsync(owner, messageBoxText, caption, button, new FontIconSource { Glyph = icon, FontSize = 30 }, defaultResult, sound); /// /// Begins an asynchronous operation to displays a message box in front of the specified window. The message box displays a message, title bar caption, button, and icon; and accepts a default message box result and returns a result. @@ -474,7 +480,7 @@ public static Task ShowAsync(Window owner, string messageBoxTe /// A value that specifies the default result of the message box. /// An asynchronous operation showing the message box. When complete, returns a . /// By default, the message box appears in front of the window that is currently active. - public static Task ShowAsync(Window owner, string messageBoxText, string caption, MessageBoxButton button, IconSource icon, MessageBoxResult? defaultResult) + public static Task ShowAsync(Window owner, string messageBoxText, string caption, MessageBoxButton button, IconSource icon, MessageBoxResult? defaultResult, SystemSound sound = null) { TaskCompletionSource taskSource = new TaskCompletionSource( #if !NET452 @@ -484,7 +490,7 @@ public static Task ShowAsync(Window owner, string messageBoxTe Application.Current.Dispatcher.Invoke(() => { - MessageBoxResult result = Show(owner, messageBoxText, caption, button, icon, defaultResult); + MessageBoxResult result = Show(owner, messageBoxText, caption, button, icon, defaultResult, sound); taskSource.TrySetResult(result); }); diff --git a/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBox.cs b/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBox.cs index 08c317e1..6272ad0f 100644 --- a/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBox.cs +++ b/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBox.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; +using System.Media; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; @@ -36,6 +37,8 @@ public MessageBoxResult Result public static BackdropType DefaultBackdropType { get; set; } = BackdropType.None; + public static bool MakeSound { get; set; } = true; + static MessageBox() { DefaultStyleKeyProperty.OverrideMetadata(typeof(MessageBox), new FrameworkPropertyMetadata(typeof(MessageBox))); @@ -52,6 +55,22 @@ public MessageBox() Loaded += On_Loaded; SystemBackdropTypeProperty_Descriptor.AddValueChanged(this, SystemBackdropTypeProperty_ValueChanged); + ThemeManager.AddActualThemeChangedHandler(this, ThemeManager_AddActualThemeChanged); + } + + private void ThemeManager_AddActualThemeChanged(object sender, RoutedEventArgs e) + { + if(WindowHelper.GetSystemBackdropType(this) != BackdropType.None) + { + if(ThemeManager.GetActualTheme(this) == ElementTheme.Dark) + { + MicaHelper.ApplyDarkMode(this); + } + else + { + MicaHelper.RemoveDarkMode(this); + } + } } private void SystemBackdropTypeProperty_ValueChanged(object sender, EventArgs e) @@ -73,6 +92,23 @@ private void SystemBackdropTypeProperty_ValueChanged(object sender, EventArgs e) } } + #region SystemSoundOnLoaded + + public static readonly DependencyProperty SystemSoundOnLoadedProperty = + DependencyProperty.Register( + nameof(SystemSoundOnLoaded), + typeof(SystemSound), + typeof(MessageBox)); + + public SystemSound SystemSoundOnLoaded + { + get => (SystemSound)GetValue(SystemSoundOnLoadedProperty); + set => SetValue(SystemSoundOnLoadedProperty, value); + } + + #endregion + + #region Caption public static readonly DependencyProperty CaptionProperty = @@ -787,7 +823,10 @@ private void On_Loaded(object sender, RoutedEventArgs e) WindowHelper.SetSystemBackdropType(this, DefaultBackdropType); } + ThemeManager_AddActualThemeChanged(sender, e); SystemBackdropTypeProperty_ValueChanged(sender, e); + + SystemSoundOnLoaded?.Play(); } private static void TryExecuteCommand(ICommand command, object parameter) diff --git a/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBoxImageExtensions.cs b/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBoxImageExtensions.cs index bb53b24c..814768a2 100644 --- a/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBoxImageExtensions.cs +++ b/source/iNKORE.UI.WPF.Modern.Controls/Controls/MessageBox/MessageBoxImageExtensions.cs @@ -1,4 +1,5 @@ using System; +using System.Media; using System.Windows; namespace iNKORE.UI.WPF.Modern.Extensions @@ -9,13 +10,28 @@ public static string ToSymbol(this MessageBoxImage image) { return image switch { - MessageBoxImage.Error => SegoeIcons.Error, + MessageBoxImage.Error => SegoeIcons.ErrorBadge, MessageBoxImage.Information => SegoeIcons.Info, MessageBoxImage.Warning => SegoeIcons.Warning, MessageBoxImage.Question => SegoeIcons.Unknown, MessageBoxImage.None => char.Parse("0x2007").ToString(), - _ => throw new NotSupportedException(), + _ => char.Parse("0x2007").ToString(), }; } + + + public static SystemSound ToAlertSound(this MessageBoxImage image) + { + return image switch + { + MessageBoxImage.Error => SystemSounds.Hand, + MessageBoxImage.Information => SystemSounds.Asterisk, + MessageBoxImage.Warning => SystemSounds.Exclamation, + MessageBoxImage.Question => SystemSounds.Question, + MessageBoxImage.None => null, + _ => null, + }; + + } } } diff --git a/source/samples/WpfApp1/MainWindow.xaml b/source/samples/WpfApp1/MainWindow.xaml index 8c3e57b2..7667e0c7 100644 --- a/source/samples/WpfApp1/MainWindow.xaml +++ b/source/samples/WpfApp1/MainWindow.xaml @@ -10,7 +10,7 @@ ui:ThemeManager.IsThemeAware="True" ui:TitleBar.Height="40" ui:TitleBar.ExtendViewIntoTitleBar="False" ui:WindowHelper.SystemBackdropType="Acrylic" ui:WindowHelper.UseModernWindowStyle="True" - ui:TitleBar.IsBackButtonVisible="False" ui:ThemeManager.RequestedTheme="Light" + ui:TitleBar.IsBackButtonVisible="False" ui:WindowHelper.CornerStyle="DoNotRound" Background="Red" Loaded="Window_Loaded"> diff --git a/source/samples/WpfApp1/MainWindow.xaml.cs b/source/samples/WpfApp1/MainWindow.xaml.cs index 3737aecd..cfed20f9 100644 --- a/source/samples/WpfApp1/MainWindow.xaml.cs +++ b/source/samples/WpfApp1/MainWindow.xaml.cs @@ -81,8 +81,8 @@ private void Button_MessageBox_Click(object sender, RoutedEventArgs e) string title = "Some title"; string message = "This is a looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong test text!"; - //System.Windows.MessageBox.Show(message, title, MessageBoxButton.YesNoCancel, MessageBoxImage.Question); - //System.Windows.MessageBox.Show("adawdawda", title, MessageBoxButton.YesNoCancel, MessageBoxImage.Question); + System.Windows.MessageBox.Show(message, title, MessageBoxButton.YesNoCancel, MessageBoxImage.Question); + System.Windows.MessageBox.Show("adawdawda", title, MessageBoxButton.YesNoCancel, MessageBoxImage.Error); MessageBoxEx.DefaultBackdropType = BackdropType.None; @@ -99,7 +99,7 @@ private void Button_MessageBox_Click(object sender, RoutedEventArgs e) MessageBoxEx.DefaultBackdropType = BackdropType.Mica; - MessageBoxEx.Show("redadwada", null, MessageBoxButton.OK, SegoeIcons.Airplane, MessageBoxResult.OK); + MessageBoxEx.Show("redadwada", null, MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK); MessageBoxEx.ShowAsync(message, title, MessageBoxButton.YesNoCancel, MessageBoxImage.Question).GetAwaiter().GetResult(); MessageBoxEx.DefaultBackdropType = BackdropType.Tabbed;