using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
namespace Aitex.Core.UI.Dialog
{
///
/// WPFMessageBox.xaml 的交互逻辑
///
public partial class WPFMessageBox : INotifyPropertyChanged
{
private bool _animationRan;
public WPFMessageBox(Window owner, string message, string details, MessageBoxButton button, MessageBoxImage icon,
MessageBoxResult defaultResult, MessageBoxOptions options)
{
_animationRan = false;
InitializeComponent();
//Owner = owner ?? Application.Current.MainWindow;
CreateButtons(button, defaultResult);
CreateImage(icon);
MessageText.Text = message;
DetailsExpander.Visibility = string.IsNullOrEmpty(details) ? Visibility.Collapsed : Visibility.Visible;
DetailsText.Text = details;
ApplyOptions(options);
}
public MessageBoxResult MessageBoxResult { get; set; }
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Create Buttons
///
/// Create the message box's button according to the user's demand
///
/// The user's buttons selection
/// The default button
private void CreateButtons(MessageBoxButton button, MessageBoxResult defaultResult)
{
switch (button)
{
case MessageBoxButton.OK:
ButtonsPanel.Children.Add(CreateOkButton(defaultResult));
break;
case MessageBoxButton.OKCancel:
ButtonsPanel.Children.Add(CreateOkButton(defaultResult));
ButtonsPanel.Children.Add(CreateCancelButton(defaultResult));
break;
case MessageBoxButton.YesNoCancel:
ButtonsPanel.Children.Add(CreateYesButton(defaultResult));
ButtonsPanel.Children.Add(CreateNoButton(defaultResult));
ButtonsPanel.Children.Add(CreateCancelButton(defaultResult));
break;
case MessageBoxButton.YesNo:
ButtonsPanel.Children.Add(CreateYesButton(defaultResult));
ButtonsPanel.Children.Add(CreateNoButton(defaultResult));
break;
default:
throw new ArgumentOutOfRangeException("button");
}
}
///
/// Create the ok button on demand
///
///
///
private Button CreateOkButton(MessageBoxResult defaultResult)
{
var okButton = new Button
{
Name = "okButton",
//Content = ((string)Application.Current.Resources["Confirm"]),
Content = "确认",
IsDefault = defaultResult == MessageBoxResult.OK,
Tag = MessageBoxResult.OK,
};
okButton.Click += ButtonClick;
return okButton;
}
///
/// Create the cancel button on demand
///
///
///
private Button CreateCancelButton(MessageBoxResult defaultResult)
{
var cancelButton = new Button
{
Name = "cancelButton",
//Content = ((string)Application.Current.Resources["Cancel"]),
Content = "取消",
IsDefault = defaultResult == MessageBoxResult.Cancel,
IsCancel = true,
Tag = MessageBoxResult.Cancel,
};
cancelButton.Click += ButtonClick;
return cancelButton;
}
///
/// Create the yes button on demand
///
///
///
private Button CreateYesButton(MessageBoxResult defaultResult)
{
var yesButton = new Button
{
Name = "yesButton",
//Content = ((string)Application.Current.Resources["Yes"]),
Content = "Yes",
IsDefault = defaultResult == MessageBoxResult.Yes,
Tag = MessageBoxResult.Yes,
};
yesButton.Click += ButtonClick;
return yesButton;
}
///
/// Create the no button on demand
///
///
///
private Button CreateNoButton(MessageBoxResult defaultResult)
{
var noButton = new Button
{
Name = "noButton",
//Content = ((string)Application.Current.Resources["No"]),
Content = "No",
IsDefault = defaultResult == MessageBoxResult.No,
Tag = MessageBoxResult.No,
};
noButton.Click += ButtonClick;
return noButton;
}
///
/// The event the buttons trigger.
/// Each button hold it's result in the tag, so here it just sets them and close the message box.
///
///
///
private void ButtonClick(object sender, RoutedEventArgs e)
{
MessageBoxResult = (MessageBoxResult)(sender as Button).Tag;
Close();
}
#endregion
private void ApplyOptions(MessageBoxOptions options)
{
if ((options & MessageBoxOptions.RightAlign) == MessageBoxOptions.RightAlign)
{
MessageText.TextAlignment = TextAlignment.Right;
DetailsText.TextAlignment = TextAlignment.Right;
}
if ((options & MessageBoxOptions.RtlReading) == MessageBoxOptions.RtlReading)
{
FlowDirection = FlowDirection.RightToLeft;
}
}
///
/// Create the image from the system's icons
///
///
private void CreateImage(MessageBoxImage icon)
{
switch (icon)
{
case MessageBoxImage.None:
ImagePlaceholder.Visibility = Visibility.Collapsed;
break;
case MessageBoxImage.Information:
ImagePlaceholder.Source = SystemIcons.Information.ToImageSource();
break;
case MessageBoxImage.Question:
ImagePlaceholder.Source = SystemIcons.Question.ToImageSource();
break;
case MessageBoxImage.Warning:
ImagePlaceholder.Source = SystemIcons.Warning.ToImageSource();
break;
case MessageBoxImage.Error:
ImagePlaceholder.Source = SystemIcons.Error.ToImageSource();
break;
default:
throw new ArgumentOutOfRangeException("icon");
}
}
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler temp = PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs(propertyName));
}
}
///
/// Enable dragging
///
///
///
private void Window_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
DragMove();
}
///
/// Show the startup animation
///
///
///
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// This is set here to height after the width has been set
// so the details expander won't stretch the message box when it's opened
SizeToContent = SizeToContent.Height;
//var animation = TryFindResource("LoadAnimation") as Storyboard;
//animation.Begin(this);
}
///
/// Show the closing animation
///
///
///
private void MessageBoxWindow_Closing(object sender, CancelEventArgs e)
{
if (!_animationRan)
{
// The animation won't run if the window is allowed to close,
// so here the animation starts, and the window's closing is canceled
e.Cancel = true;
var animation = TryFindResource("UnloadAnimation") as Storyboard;
animation.Completed += AnimationCompleted;
animation.Begin(this);
}
}
///
/// Signals the closing animation ran, and close the window (for real this time)
///
///
///
private void AnimationCompleted(object sender, EventArgs e)
{
_animationRan = true;
Close();
}
#region Show Information
///
/// Display an information message
///
/// The message text
/// The details part text
/// Display the cancel
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowInformation(string message, string details = "", bool showCancel = false,
MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowInformation(null, message, details, showCancel, options);
}
///
/// Display an information message
///
/// The message box's parent window
/// The message text
/// The details part text
/// Display the cancel
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowInformation(Window owner, string message, string details = "",
bool showCancel = false,
MessageBoxOptions options = MessageBoxOptions.None)
{
return Show(owner, message, details, showCancel ? MessageBoxButton.OKCancel : MessageBoxButton.OK,
MessageBoxImage.Information, MessageBoxResult.OK, options);
}
#endregion
#region Show Question
///
/// Display a question
///
/// The message text
/// The details part text
/// Display the cancel
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowQuestion(string message, string details = "",
bool showCancel = false,
MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowQuestion(null, message, details, showCancel, options);
}
///
/// Display a question
///
/// The message box's parent window
/// The message text
/// The details part text
/// Display the cancel
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowQuestion(Window owner, string message, string details = "",
bool showCancel = false,
MessageBoxOptions options = MessageBoxOptions.None)
{
return Show(owner, message, details, showCancel ? MessageBoxButton.YesNoCancel : MessageBoxButton.YesNo,
MessageBoxImage.Question, MessageBoxResult.Yes, options);
}
#endregion
#region Show Warning
///
/// Display a warning
///
/// The message text
/// The details part text
/// Display the cancel
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowWarning(string message, string details = "",
bool showCancel = false,
MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowWarning(null, message, details, showCancel, options);
}
///
/// Display a warning
///
/// The message box's parent window
/// The message text
/// The details part text
/// Display the cancel
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowWarning(Window owner, string message, string details = "",
bool showCancel = false,
MessageBoxOptions options = MessageBoxOptions.None)
{
return Show(owner, message, details, showCancel ? MessageBoxButton.OKCancel : MessageBoxButton.OK,
MessageBoxImage.Warning, MessageBoxResult.OK, options);
}
#endregion
#region Show Error
///
/// Display an Error
///
/// Display the exception's details
/// The message text
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowError(Exception exception, string message = "",
MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowError(null, exception, message, options);
}
///
/// Display an Error
///
/// The message text
/// The details part text
/// Display the cancel
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowError(string message, string details = "",
bool showCancel = false,
MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowError(null, message, details, showCancel, options);
}
///
/// Display an Error
///
/// The message box's parent window
/// Display the exception's details
/// The message text
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowError(Window owner, Exception exception, string message = "",
MessageBoxOptions options = MessageBoxOptions.None)
{
string details = string.Empty;
#if DEBUG
details = exception.ToString();
#endif
return Show(owner, String.IsNullOrEmpty(message) ? exception.Message : message, details, MessageBoxButton.OK,
MessageBoxImage.Error, MessageBoxResult.OK, options);
}
///
/// Display an Error
///
/// The message box's parent window
/// The message text
/// The details part text
/// Display the cancel
/// Misc options
/// The user's selected button
public static MessageBoxResult ShowError(Window owner, string message, string details = "",
bool showCancel = false,
MessageBoxOptions options = MessageBoxOptions.None)
{
return Show(owner, message, details, showCancel ? MessageBoxButton.OKCancel : MessageBoxButton.OK,
MessageBoxImage.Error, MessageBoxResult.OK, options);
}
#endregion
#region Show
///
/// Show the message box with the specified parameters
///
/// The message text
/// The details part text
/// The buttons to be displayed
/// The message's severity
/// The default button
/// Misc options
/// The user's selected button
public static MessageBoxResult Show(string message, string details = "",
MessageBoxButton button = MessageBoxButton.OK,
MessageBoxImage icon = MessageBoxImage.None,
MessageBoxResult defaultResult = MessageBoxResult.None,
MessageBoxOptions options = MessageBoxOptions.None)
{
return Show(null, message, details, button, icon, defaultResult, options);
}
///
/// Show the message box with the specified parameters
///
/// The message text
/// The buttons to be displayed
/// The message's severity
/// The default button
/// Misc options
/// The user's selected button
public static MessageBoxResult Show(string message,
MessageBoxButton button = MessageBoxButton.OK,
MessageBoxImage icon = MessageBoxImage.None,
MessageBoxResult defaultResult = MessageBoxResult.None,
MessageBoxOptions options = MessageBoxOptions.None)
{
return Show(message, string.Empty, button, icon, defaultResult, options);
}
///
/// Show the message box with the specified parameters
///
/// The message box's parent window
/// The message text
/// The buttons to be displayed
/// The message's severity
/// The default button
/// Misc options
/// The user's selected button
public static MessageBoxResult Show(Window owner, string message,
MessageBoxButton button = MessageBoxButton.OK,
MessageBoxImage icon = MessageBoxImage.None,
MessageBoxResult defaultResult = MessageBoxResult.None,
MessageBoxOptions options = MessageBoxOptions.None)
{
return Show(owner, message, string.Empty, button, icon, defaultResult, options);
}
///
/// Show the message box with the specified parameters
///
/// The message box's parent window
/// The message text
/// The details part text
/// The buttons to be displayed
/// The message's severity
/// The default button
/// Misc options
/// The user's selected button
public static MessageBoxResult Show(Window owner, string message, string details = "",
MessageBoxButton button = MessageBoxButton.OK,
MessageBoxImage icon = MessageBoxImage.None,
MessageBoxResult defaultResult = MessageBoxResult.None,
MessageBoxOptions options = MessageBoxOptions.None)
{
var result = Application.Current.Dispatcher.Invoke(new Func(() =>
{
var messageBox = new WPFMessageBox(owner, message, details, button, icon, defaultResult, options);
messageBox.ShowDialog();
return messageBox.MessageBoxResult;
}));
return (MessageBoxResult)result;
}
#endregion
}
public static class IconHelper
{
[DllImport("gdi32.dll", SetLastError = true)]
private static extern bool DeleteObject(IntPtr hObject);
public static ImageSource ToImageSource(this Icon icon)
{
Bitmap bitmap = icon.ToBitmap();
IntPtr hBitmap = bitmap.GetHbitmap();
ImageSource wpfBitmap = Imaging.CreateBitmapSourceFromHBitmap(
hBitmap,
IntPtr.Zero,
Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
if (!DeleteObject(hBitmap))
{
throw new Win32Exception();
}
return wpfBitmap.GetAsFrozen() as ImageSource;
}
}
}