是否可以向MessageBox添加自定义样式?
MessageBox.Show("Bla bla", "Error");
我想改变这个窗口的外观。我有什么选择?
答案 0 :(得分:2)
这将有助于创建自定义消息框
Background="Transparent" Closing="MessageBoxWindow_Closing"
Loaded="Window_Loaded" RenderTransformOrigin="0.5, 0.5"
ResizeMode="NoResize" ShowInTaskbar="False"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterOwner" WindowStyle="None">
<Window.RenderTransform>
<ScaleTransform x:Name="Scale"/>
</Window.RenderTransform>
<Window.Resources>
<LinearGradientBrush x:Key="BackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="#E4E9F0"/>
<GradientStop Offset="1" Color="#D5DDED"/>
</LinearGradientBrush>
<Style TargetType="Label">
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="FontSize" Value="12pt"/>
<Setter Property="Foreground" Value="#FF003399"/>
</Style>
<Style TargetType="Image">
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="32"/>
<Setter Property="Margin" Value="3"/>
</Style>
<Storyboard x:Key="LoadAnimation">
<DoubleAnimation AccelerationRatio="0.4" Duration="00:00:00.15" From="0.6" Storyboard.TargetName="Scale" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="1.1"/>
<DoubleAnimation AccelerationRatio="0.4" Duration="00:00:00.15" From="0.6" Storyboard.TargetName="Scale" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="1.1"/>
<DoubleAnimation AccelerationRatio="0.4" Duration="00:00:00.15" From="0" Storyboard.TargetName="MessageBoxWindow" Storyboard.TargetProperty="(Window.Opacity)" To="1"/>
<DoubleAnimation BeginTime="00:00:00.15" Duration="00:00:00.1" From="1.1" Storyboard.TargetName="Scale" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="1"/>
<DoubleAnimation BeginTime="00:00:00.15" Duration="00:00:00.1" From="1.1" Storyboard.TargetName="Scale" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="1"/>
</Storyboard>
<Storyboard x:Key="UnloadAnimation">
<DoubleAnimation AccelerationRatio="0.4" Duration="00:00:00.2" From="1" Storyboard.TargetName="Scale" Storyboard.TargetProperty="(ScaleTransform.ScaleX)" To="0.6"/>
<DoubleAnimation AccelerationRatio="0.4" Duration="00:00:00.2" From="1" Storyboard.TargetName="Scale" Storyboard.TargetProperty="(ScaleTransform.ScaleY)" To="0.6"/>
<DoubleAnimation AccelerationRatio="0.4" Duration="00:00:00.2" From="1" Storyboard.TargetName="MessageBoxWindow" Storyboard.TargetProperty="(Window.Opacity)" To="0"/>
</Storyboard>
<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="15"/>
<Setter Property="Width" Value="124"/>
<Setter Property="Height" Value="42"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="CancelButton" Source="pack://application:,,,/V-Coles;component/Resources/Images/openlockerbtn.png" />
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsDefaulted" Value="true">
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Source" TargetName="CancelButton" Value="pack://application:,,,/V-Coles;component/Resources/Images/openlockerbtnhover.png"/>
</Trigger>
<Trigger Property="IsPressed" Value="true">
<Setter Property="Source" TargetName="CancelButton" Value="pack://application:,,,/V-Coles;component/Resources/Images/openlockerbtnhover.png"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Border Height="150" Width="300" Background="#dd4739" Padding="7" Margin="50,100,50,50">
<DockPanel LastChildFill="True">
<StackPanel x:Name="ButtonsPanel" HorizontalAlignment="Center" DockPanel.Dock="Bottom" Orientation="Horizontal"/>
<Image x:Name="ImagePlaceholder" DockPanel.Dock="Left"/>
<Label x:Name="MessageLabel" DockPanel.Dock="Right">
<TextBlock x:Name="MessageText" Foreground="Black" TextWrapping="Wrap"/>
</Label>
</DockPanel>
</Border>
</Window>
public partial class MessageBox : INotifyPropertyChanged
{
#region Private Field
private bool _animationRan;
#endregion
#region Constructor
public MessageBox(Window owner, string message, string details, MessageBoxButton button, MessageBoxImage icon, MessageBoxResult defaultResult, MessageBoxOptions options)
{
this._animationRan = false;
this.InitializeComponent();
Owner = owner ?? Application.Current.MainWindow;
this.CreateButtons(button, defaultResult);
this.CreateImage(icon);
MessageText.Text = message;
this.ApplyOptions(options);
}
#endregion
#region Event Property
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Public Property
/// <summary>
/// Gets or sets a value indicating whether the IsActiveMessageBox
/// </summary>
public static bool IsActiveMessageBox { get; set; }
public static Window ActiveMessageBox { get; set; }
public MessageBoxResult MessageBoxResult { get; set; }
#endregion
#region Public Static Method
public static MessageBoxResult ShowInformation(string message, string details = "", bool showCancel = false, MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowInformation(null, message, details, showCancel, options);
}
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);
}
public static MessageBoxResult ShowQuestion(string message, string details = "", bool showCancel = false, MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowQuestion(null, message, details, showCancel, options);
}
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);
}
public static MessageBoxResult ShowWarning(string message, string details = "", bool showCancel = false, MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowWarning(null, message, details, showCancel, options);
}
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);
}
public static MessageBoxResult ShowError(Exception exception, string message = "", MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowError(null, exception, message, options);
}
public static MessageBoxResult ShowError(string message, string details = "", bool showCancel = false, MessageBoxOptions options = MessageBoxOptions.None)
{
return ShowError(null, message, details, showCancel, options);
}
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);
}
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);
}
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);
}
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);
}
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);
}
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)
{
MessageBoxResult result = MessageBoxResult.None;
result = Application.Current.Dispatcher.Invoke(new Func<MessageBoxResult>(() =>
{
var messageBox = new MessageBox(owner, message, details, button, icon, defaultResult, options);
IsActiveMessageBox = true;
ActiveMessageBox = messageBox;
messageBox.ShowDialog();
return messageBox.MessageBoxResult;
}));
if (result != MessageBoxResult.None)
{
return (MessageBoxResult)result;
}
else
{
return MessageBoxResult.None;
}
}
#endregion
#region Public Method
public void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler temp = this.PropertyChanged;
if (temp != null)
{
temp(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
#region Private Method
private void CreateButtons(MessageBoxButton button, MessageBoxResult defaultResult)
{
switch (button)
{
case MessageBoxButton.OK:
ButtonsPanel.Children.Add(this.CreateOkButton(defaultResult));
break;
case MessageBoxButton.OKCancel:
ButtonsPanel.Children.Add(this.CreateOkButton(defaultResult));
ButtonsPanel.Children.Add(this.CreateCancelButton(defaultResult));
break;
case MessageBoxButton.YesNoCancel:
ButtonsPanel.Children.Add(this.CreateYesButton(defaultResult));
ButtonsPanel.Children.Add(this.CreateNoButton(defaultResult));
ButtonsPanel.Children.Add(this.CreateCancelButton(defaultResult));
break;
case MessageBoxButton.YesNo:
ButtonsPanel.Children.Add(this.CreateYesButton(defaultResult));
ButtonsPanel.Children.Add(this.CreateNoButton(defaultResult));
break;
default:
throw new ArgumentOutOfRangeException("button");
}
}
private Button CreateOkButton(MessageBoxResult defaultResult)
{
var okButton = new Button
{
Name = "okButton",
Content = "OK",
IsDefault = defaultResult == MessageBoxResult.OK,
Tag = MessageBoxResult.OK,
};
okButton.Click += this.ButtonClick;
return okButton;
}
private Button CreateCancelButton(MessageBoxResult defaultResult)
{
var cancelButton = new Button
{
Name = "cancelButton",
Content = "Cancel",
IsDefault = defaultResult == MessageBoxResult.Cancel,
IsCancel = true,
Tag = MessageBoxResult.Cancel,
};
cancelButton.Click += this.ButtonClick;
return cancelButton;
}
private Button CreateYesButton(MessageBoxResult defaultResult)
{
var yesButton = new Button
{
Name = "yesButton",
Content = "Yes",
IsDefault = defaultResult == MessageBoxResult.Yes,
Tag = MessageBoxResult.Yes,
};
yesButton.Click += this.ButtonClick;
return yesButton;
}
private Button CreateNoButton(MessageBoxResult defaultResult)
{
var noButton = new Button
{
Name = "noButton",
Content = "No",
IsDefault = defaultResult == MessageBoxResult.No,
Tag = MessageBoxResult.No,
};
noButton.Click += this.ButtonClick;
return noButton;
}
private void ButtonClick(object sender, RoutedEventArgs e)
{
MessageBoxResult = (MessageBoxResult)(sender as Button).Tag;
Close();
}
private void ApplyOptions(MessageBoxOptions options)
{
if ((options & MessageBoxOptions.RightAlign) == MessageBoxOptions.RightAlign)
{
MessageText.TextAlignment = TextAlignment.Right;
}
if ((options & MessageBoxOptions.RtlReading) == MessageBoxOptions.RtlReading)
{
FlowDirection = FlowDirection.RightToLeft;
}
}
/// <summary>
/// Create the image from the system's icons
/// </summary>
/// <param name="icon">MessageBox Icon</param>
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");
}
}
/// <summary>
/// Show the startup animation
/// </summary>
/// <param name="sender">Sender parameter</param>
/// <param name="e">Argument Parameter</param>
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);
}
/// <summary>
/// Show the closing animation
/// </summary>
/// <param name="sender">Sender parameter</param>
/// <param name="e">Argument Parameter</param>
private void MessageBoxWindow_Closing(object sender, CancelEventArgs e)
{
if (!this._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 += this.AnimationCompleted;
animation.Begin(this);
}
}
/// <summary>
/// Signals the closing animation ran, and close the window (for real this time)
/// </summary>
/// <param name="sender">Sender parameter</param>
/// <param name="e">Argument Parameter</param>
private void AnimationCompleted(object sender, EventArgs e)
{
this._animationRan = true;
Close();
}
#endregion
}