【转】WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox
一.前言
申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等。
本文主要内容:
- 自定义Window窗体样式;
- 基于自定义窗体实现自定义MessageBox消息提示框;
二.自定义Window窗体样式
自定义的Window窗体效果:
因为WPF默认的窗体比较简陋,大都需要自己实现Window窗体样式效果,基本思路很简单:
- 第一步:干掉默认样式:WindowStyle = WindowStyle.None;
- 第二步:设置窗体透明:AllowsTransparency = true;
- 第三步:设置自己的窗体样式;
这样从外观样式上可以满足,但做为窗体该具备的基本功能还没有,需要另外来实现了:
- 窗体Icon、标题栏(可以通过样式实现);
- 窗体的基本按钮:最小化、最大化、关闭按钮;
- 窗体的鼠标拖动;
- 好像Win8、Win10的功能吧,窗体拖动到桌面边缘自动最大化、还原;
- 鼠标调整窗口大小;
- 双击标题栏最大化、还原;
上面的功能在本文中,一部分是自定义实现的,还有一部分是用了一个开源库(Microsoft.Windows.Shell)用于实现窗体大小、拖放等窗体基本功能,Microsoft.Windows.Shell文件下载:点我下载。
进入正题,自定义窗体WindowBase的后台C#代码:
/// <summary> /// WindowBase.xaml 的交互逻辑 /// </summary> public class WindowBase : Window { #region 默认Header:窗体字体图标FIcon public static readonly DependencyProperty FIconProperty = DependencyProperty.Register("FIcon", typeof(string), typeof(WindowBase), new PropertyMetadata("\ue62e")); /// <summary> /// 按钮字体图标编码 /// </summary> public string FIcon { get { return (string)GetValue(FIconProperty); } set { SetValue(FIconProperty, value); } } #endregion #region 默认Header:窗体字体图标大小 public static readonly DependencyProperty FIconSizeProperty = DependencyProperty.Register("FIconSize", typeof(double), typeof(WindowBase), new PropertyMetadata(20D)); /// <summary> /// 按钮字体图标大小 /// </summary> public double FIconSize { get { return (double)GetValue(FIconSizeProperty); } set { SetValue(FIconSizeProperty, value); } } #endregion #region CaptionHeight 标题栏高度 public static readonly DependencyProperty CaptionHeightProperty = DependencyProperty.Register("CaptionHeight", typeof(double), typeof(WindowBase), new PropertyMetadata(26D)); /// <summary> /// 标题高度 /// </summary> public double CaptionHeight { get { return (double)GetValue(CaptionHeightProperty); } set { SetValue(CaptionHeightProperty, value); //this._WC.CaptionHeight = value; } } #endregion #region CaptionBackground 标题栏背景色 public static readonly DependencyProperty CaptionBackgroundProperty = DependencyProperty.Register( "CaptionBackground", typeof(Brush), typeof(WindowBase), new PropertyMetadata(null)); public Brush CaptionBackground { get { return (Brush)GetValue(CaptionBackgroundProperty); } set { SetValue(CaptionBackgroundProperty, value); } } #endregion #region CaptionForeground 标题栏前景景色 public static readonly DependencyProperty CaptionForegroundProperty = DependencyProperty.Register( "CaptionForeground", typeof(Brush), typeof(WindowBase), new PropertyMetadata(null)); public Brush CaptionForeground { get { return (Brush)GetValue(CaptionForegroundProperty); } set { SetValue(CaptionForegroundProperty, value); } } #endregion #region Header 标题栏内容模板,以提高默认模板,可自定义 public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register( "Header", typeof(ControlTemplate), typeof(WindowBase), new PropertyMetadata(null)); public ControlTemplate Header { get { return (ControlTemplate)GetValue(HeaderProperty); } set { SetValue(HeaderProperty, value); } } #endregion #region MaxboxEnable 是否显示最大化按钮 public static readonly DependencyProperty MaxboxEnableProperty = DependencyProperty.Register( "MaxboxEnable", typeof(bool), typeof(WindowBase), new PropertyMetadata(true)); public bool MaxboxEnable { get { return (bool)GetValue(MaxboxEnableProperty); } set { SetValue(MaxboxEnableProperty, value); } } #endregion #region MinboxEnable 是否显示最小化按钮 public static readonly DependencyProperty MinboxEnableProperty = DependencyProperty.Register( "MinboxEnable", typeof(bool), typeof(WindowBase), new PropertyMetadata(true)); public bool MinboxEnable { get { return (bool)GetValue(MinboxEnableProperty); } set { SetValue(MinboxEnableProperty, value); } } #endregion public WindowBase() { this.WindowStyle = WindowStyle.None; this.AllowsTransparency = true; this.WindowStartupLocation = WindowStartupLocation.CenterScreen; this.Style = this.FindResource("DefaultWindowStyle") as Style; this.Icon = Images.CreateImageSourceFromImage(Properties.Resources.logo); //12=6+6//Margin=6,Border.Effect.BlueRadius=6 this.MaxHeight = SystemParameters.WorkArea.Height + 12 + 2; //bind command this.BindCommand(SystemCommands.CloseWindowCommand, this.CloseCommand_Execute); this.BindCommand(ApplicationCommands.Close, this.CloseCommand_Execute); this.BindCommand(SystemCommands.MaximizeWindowCommand, this.MaxCommand_Execute); this.BindCommand(SystemCommands.MinimizeWindowCommand, this.MinCommand_Execute); } private void CloseCommand_Execute(object sender, ExecutedRoutedEventArgs e) { SystemCommands.CloseWindow(this); } private void MaxCommand_Execute(object sender, ExecutedRoutedEventArgs e) { this.WindowState = this.WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized; e.Handled = true; } private void MinCommand_Execute(object sender, ExecutedRoutedEventArgs e) { this.WindowState = WindowState.Minimized; e.Handled = true; } protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); if (e.ButtonState == MouseButtonState.Pressed) { this.DragMove(); } } }
绑定命令的扩展方法:
/// <summary> /// 绑定命令和命令事件到宿主UI /// </summary> public static void BindCommand(this UIElement @ui, ICommand com, Action<object, ExecutedRoutedEventArgs> call) { var bind = new CommandBinding(com); bind.Executed += new ExecutedRoutedEventHandler(call); @ui.CommandBindings.Add(bind); }
WindowBase的样式有两个,一个是基础样式BaseWindowStyle,可以自定义头部标题栏,提供更多定制需求。另一个样式DefaultWindowStyle为默认窗体样式,用于大多数不要特别定制的窗体需求。BaseWindowStyle样式代码:
<!--WindowBase基本样式,可以自定义头部--> <Style x:Key="BaseWindowStyle" TargetType="{x:Type local:WindowBase}"> <Setter Property="Background" Value="{StaticResource WindowBackground}"/> <Setter Property="Foreground" Value="{StaticResource TextForeground}"/> <Setter Property="FontSize" Value="{StaticResource FontSize}"/> <Setter Property="FontFamily" Value="{StaticResource FontFamily}"/> <Setter Property="Width" Value="480"/> <Setter Property="Height" Value="320"/> <Setter Property="BorderBrush" Value="{StaticResource WindowBorderBrush}"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="FIconSize" Value="20"/> <Setter Property="CaptionHeight" Value="26"/> <Setter Property="ResizeMode" Value="CanResizeWithGrip"/> <!--标题栏背景色--> <Setter Property="CaptionBackground" Value="{StaticResource CaptionBackground}" /> <Setter Property="CaptionForeground" Value="{StaticResource CaptionForeground}" /> <Setter Property="FIcon" Value=""/> <Setter Property="MaxboxEnable" Value="True"/> <Setter Property="MinboxEnable" Value="True"/> <!--建议内边框=3:ResizeBorderThickness = new Thickness(3);--> <Setter Property="Padding" Value="3"/> <Setter Property="local:ControlAttachProperty.CornerRadius" Value="0"/> <!--窗体基本设置 shell:WindowChrome--> <Setter Property="shell:WindowChrome.WindowChrome"> <Setter.Value> <shell:WindowChrome CaptionHeight="{Binding Path=CaptionHeight,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type local:WindowBase}}}" ResizeBorderThickness="8"/> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:WindowBase}"> <Grid Margin="6"> <!--背景,边框--> <Border x:Name="Bg" CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Effect="{StaticResource WindowDropShadow}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> <Border x:Name="BgInner" CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}" Background="{StaticResource WindowInnerBackground}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> <!--内容区域--> <AdornerDecorator> <ContentPresenter Margin="1" Content="{TemplateBinding Content}" /> </AdornerDecorator> <!--窗体功能按钮:最小、最大、关闭--> <Border VerticalAlignment="Top" Height="{TemplateBinding CaptionHeight}" Width="Auto" Margin="1" HorizontalAlignment="Right"> <StackPanel Orientation="Horizontal" VerticalAlignment="{TemplateBinding VerticalAlignment}" Height="30"> <local:FButton x:Name="btnMin" Width="26" VerticalAlignment="Center" Margin="1,2,1,2" Visibility="{Binding Path=MinboxEnable,RelativeSource={RelativeSource TemplatedParent},Converter={x:Static local:XConverter.BooleanToVisibilityConverter}}" Style="{StaticResource FButton_Transparency}" FIcon="" FIconSize="16" shell:WindowChrome.IsHitTestVisibleInChrome="True" Foreground="{TemplateBinding CaptionForeground}" Command="{x:Static shell:SystemCommands.MinimizeWindowCommand}"/> <local:FButton x:Name="btnMax" Width="26" VerticalAlignment="Center" Margin="1,2,1,2" Visibility="{Binding Path=MaxboxEnable,RelativeSource={RelativeSource TemplatedParent},Converter={x:Static local:XConverter.BooleanToVisibilityConverter}}" Style="{StaticResource FButton_Transparency}" FIcon="" FIconSize="16" shell:WindowChrome.IsHitTestVisibleInChrome="True" Foreground="{TemplateBinding CaptionForeground}" Command="{x:Static shell:SystemCommands.MaximizeWindowCommand}"/> <local:FButton x:Name="btnClose" Width="38" VerticalAlignment="Center" Margin="1,2,3,2" CornerRadius="0" MouseOverBackground="Red" MouseOverForeground="White" PressedBackground="#AA0D0D" PressedForeground="White" AllowsAnimation="True" Style="{StaticResource FButton_Transparency}" FIcon="" FIconSize="16" shell:WindowChrome.IsHitTestVisibleInChrome="True" FIconMargin="0" Foreground="{TemplateBinding CaptionForeground}" Command="{x:Static shell:SystemCommands.CloseWindowCommand}"/> </StackPanel> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="WindowState" Value="Maximized"> <Setter Property="FIcon" TargetName="btnMax" Value=""></Setter> </Trigger> <Trigger Property="WindowState" Value="Normal"> <Setter Property="FIcon" TargetName="btnMax" Value=""></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
DefaultWindowStyle样式代码:
<!--默认WindowBase的样式--> <Style x:Key="DefaultWindowStyle" TargetType="{x:Type local:WindowBase}"> <Setter Property="Background" Value="{StaticResource WindowBackground}"/> <Setter Property="Foreground" Value="{StaticResource TextForeground}"/> <Setter Property="FontSize" Value="{StaticResource FontSize}"/> <Setter Property="FontFamily" Value="{StaticResource FontFamily}"/> <Setter Property="Width" Value="480"/> <Setter Property="Height" Value="320"/> <Setter Property="BorderBrush" Value="{StaticResource WindowBorderBrush}"/> <Setter Property="BorderThickness" Value="1"/> <Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="FIconSize" Value="20"/> <Setter Property="CaptionHeight" Value="26"/> <Setter Property="ResizeMode" Value="CanResizeWithGrip"/> <!--标题栏背景色--> <Setter Property="CaptionBackground" Value="{StaticResource CaptionBackground}" /> <Setter Property="CaptionForeground" Value="{StaticResource CaptionForeground}" /> <Setter Property="FIcon" Value=""/> <Setter Property="MaxboxEnable" Value="True"/> <Setter Property="MinboxEnable" Value="True"/> <!--建议内边框=3:ResizeBorderThickness = new Thickness(3);--> <Setter Property="Padding" Value="3"/> <Setter Property="local:ControlAttachProperty.CornerRadius" Value="0"/> <!--窗体基本设置 shell:WindowChrome--> <Setter Property="shell:WindowChrome.WindowChrome"> <Setter.Value> <shell:WindowChrome CaptionHeight="{Binding Path=CaptionHeight,RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type local:WindowBase}}}" ResizeBorderThickness="8"/> </Setter.Value> </Setter> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type local:WindowBase}"> <Grid Margin="6"> <!--背景--> <Border x:Name="Bg" CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" Effect="{StaticResource WindowDropShadow}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> <Border x:Name="BgInner" CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}" Background="{StaticResource WindowInnerBackground}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> <Grid Margin="1"> <Grid.RowDefinitions> <RowDefinition MinHeight="18" Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <!--Caption标题部分--> <Border Margin="0" Grid.Row="0" Background="{TemplateBinding CaptionBackground}"> <Grid Margin="2,1,2,0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <!--Header部分--> <StackPanel x:Name="PART_Header" Height="{TemplateBinding CaptionHeight}" Margin="5,1,5,1" Orientation="Horizontal" VerticalAlignment="Center"> <TextBlock Style="{StaticResource FIcon}" Foreground="{TemplateBinding CaptionForeground}" FontSize="{TemplateBinding FIconSize}" Text="{TemplateBinding FIcon}"/> <TextBlock VerticalAlignment="Center" Margin="5" FontSize="{StaticResource HeaderFontSize}" Foreground="{TemplateBinding CaptionForeground}" Text="{TemplateBinding Title}"/> </StackPanel> <!--窗体功能按钮:最小、最大、关闭--> <StackPanel Grid.Column="1" Orientation="Horizontal" VerticalAlignment="Top" Margin="1" HorizontalAlignment="Right" Height="{TemplateBinding CaptionHeight}"> <local:FButton x:Name="btnMin" Width="26" VerticalAlignment="Center" Margin="1" Visibility="{Binding Path=MinboxEnable,RelativeSource={RelativeSource TemplatedParent},Converter={x:Static local:XConverter.BooleanToVisibilityConverter}}" Style="{StaticResource FButton_Transparency}" FIcon="" FIconSize="14" shell:WindowChrome.IsHitTestVisibleInChrome="True" Foreground="{TemplateBinding CaptionForeground}" Command="{x:Static shell:SystemCommands.MinimizeWindowCommand}"/> <local:FButton x:Name="btnMax" Width="26" VerticalAlignment="Center" Margin="1" Visibility="{Binding Path=MaxboxEnable,RelativeSource={RelativeSource TemplatedParent},Converter={x:Static local:XConverter.BooleanToVisibilityConverter}}" Style="{StaticResource FButton_Transparency}" FIcon="" FIconSize="14" shell:WindowChrome.IsHitTestVisibleInChrome="True" Foreground="{TemplateBinding CaptionForeground}" Command="{x:Static shell:SystemCommands.MaximizeWindowCommand}"/> <local:FButton x:Name="btnClose" Width="35" VerticalAlignment="Center" Margin="1" CornerRadius="0" Padding="1 2 1 2" MouseOverBackground="Red" MouseOverForeground="White" PressedBackground="#AA0D0D" PressedForeground="White" AllowsAnimation="True" Style="{StaticResource FButton_Transparency}" FIcon="" FIconSize="14" shell:WindowChrome.IsHitTestVisibleInChrome="True" FIconMargin="0" Foreground="{TemplateBinding CaptionForeground}" Command="{x:Static shell:SystemCommands.CloseWindowCommand}"/> </StackPanel> </Grid> </Border> <!--窗体内容区域--> <AdornerDecorator Grid.Row="1" Margin="3,0,3,3"> <ContentPresenter Content="{TemplateBinding Content}" /> </AdornerDecorator> </Grid> </Grid> <ControlTemplate.Triggers> <Trigger Property="WindowState" Value="Maximized"> <Setter Property="FIcon" TargetName="btnMax" Value=""></Setter> </Trigger> <Trigger Property="WindowState" Value="Normal"> <Setter Property="FIcon" TargetName="btnMax" Value=""></Setter> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
上面效果的背景色彩、边框的资源:
<!--Window窗体--> <SolidColorBrush x:Key="WindowBackground" Color="#093B5D"></SolidColorBrush> <SolidColorBrush x:Key="WindowInnerBackground" Color="Transparent"></SolidColorBrush> <!--<ImageBrush x:Key="WindowInnerBackground" Stretch="Fill" ImageSource="pack://application:,,,/XLY.Framework.WPFTest;component/Images/back/b2.jpg" Opacity="1" Viewport="0,0,1,1" ViewportUnits="Absolute" TileMode="Tile" AlignmentX="Left" AlignmentY="Top"/>--> <SolidColorBrush x:Key="WindowBorderBrush" Color="#920892"></SolidColorBrush> <DropShadowEffect x:Key="WindowDropShadow" Color="#F472F4" BlurRadius="8" ShadowDepth="0" Direction="0" Opacity="0.7" /> <SolidColorBrush x:Key="CaptionForeground" Color="White"></SolidColorBrush> <!--<LinearGradientBrush x:Key="CaptionBackground" StartPoint="0.5,0" EndPoint="0.5,1"> <GradientStop Color="#571457" Offset="0"/> <GradientStop Color="#6A196A" Offset="1"/> </LinearGradientBrush>--> <ImageBrush x:Key="CaptionBackground" ImageSource="pack://application:,,,/XLY.Framework.WPFTest;component/Images/back/b2.jpg" Opacity="1" Viewport="0,0,202,143" ViewportUnits="Absolute" TileMode="Tile" AlignmentX="Left" AlignmentY="Top"/>
三.实现自定义MessageBox消息提示框
基于第二节自定义的窗体WindowBase,实现自定义的MessageBox就简单了,效果图:
仔细观察,不难发现上面的窗体大小是根据内容的多少自适应的。窗体自适应内容的的关键设置就是SizeToContent="WidthAndHeight",但为了达到更好的效果控制,还需要控制内容的大小范围,范围可以自己调整,看了样式代码你就了解了:
<local:WindowBase x:Class="System.Windows.MessageBoxX" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell" xmlns:local="clr-namespace:XLY.Framework.Controls" MaxboxEnable="False" MinboxEnable="False" ResizeMode="NoResize" FIcon="" x:Name="mb" Title="MessageBox" ShowInTaskbar="False" SizeToContent="WidthAndHeight" Style="{StaticResource DefaultWindowStyle}" CaptionHeight="24"> <local:WindowBase.InputBindings> <KeyBinding Key="Escape" Command="{x:Static shell:SystemCommands.CloseWindowCommand}"/> </local:WindowBase.InputBindings> <Grid> <Grid Margin="5,8,5,5"> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="60"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="100"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <TextBlock x:Name="ficon" HorizontalAlignment="Right" FontSize="80" Text="" Foreground="{Binding Foreground,ElementName=mb}" Style="{StaticResource FIcon}" Margin="5"/> <TextBlock x:Name="txtMessage" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Foreground="{Binding Foreground,ElementName=mb}" FontSize="{Binding FontSize,ElementName=mb}" TextWrapping="Wrap" Margin="5,20,10,20" MinWidth="260" MaxWidth="420">新建一个WPF程序在Windows8下面就会出现左边的窗口边框,颜色取决于Windows主题我想在想创建一个右边那样的窗口,要么是窄边,要么没有边</TextBlock> <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="1" Grid.Column="0" Grid.Row="1" Grid.ColumnSpan="2" HorizontalAlignment="Center"> <local:FButton x:Name="btnOK" FIcon="" Width="85" Height="30" CornerRadius="0" Margin="5,5,20,5" Click="btnOK_Click">确定</local:FButton> <local:FButton x:Name="btnCancel" FIcon="" Width="85" Height="30" CornerRadius="0" Margin="20,5,10,5" Click="btnCancel_Click">取消</local:FButton> </StackPanel> </Grid> </Grid> </local:WindowBase>
上面不同消息类型的颜色资源:
<!--MessageBoxX--> <SolidColorBrush x:Key="InfoForeground" Color="White"></SolidColorBrush> <SolidColorBrush x:Key="QuestionForeground" Color="#74B80C"></SolidColorBrush> <SolidColorBrush x:Key="WarningForeground" Color="DarkOrange"></SolidColorBrush> <SolidColorBrush x:Key="ErrorForeground" Color="#E74E4E"></SolidColorBrush>
后台C#代码
/// <summary> /// MessageBoxXxaml.xaml 的交互逻辑 /// </summary> public partial class MessageBoxX : WindowBase { /// <summary> /// 结果,用户点击确定Result=true; /// </summary> public bool Result { get; private set; } private static readonly Dictionary<string, Brush> _Brushes = new Dictionary<string, Brush>(); public MessageBoxX(EnumNotifyType type, string mes) { InitializeComponent(); this.txtMessage.Text = mes; //type btnCancel.Visibility = Visibility.Collapsed; this.SetForeground(type); switch (type) { case EnumNotifyType.Error: this.ficon.Text = "\ue644"; break; case EnumNotifyType.Warning: this.ficon.Text = "\ue60b"; break; case EnumNotifyType.Info: this.ficon.Text = "\ue659"; break; case EnumNotifyType.Question: this.ficon.Text = "\ue60e"; this.btnCancel.Visibility = Visibility.Visible; break; } } private void SetForeground(EnumNotifyType type) { string key = type.ToSafeString() + "Foreground"; if (!_Brushes.ContainsKey(key)) { var b = this.TryFindResource(key) as Brush; _Brushes.Add(key, b); } this.Foreground = _Brushes[key]; } private void btnOK_Click(object sender, RoutedEventArgs e) { this.Result = true; this.Close(); e.Handled = true; } private void btnCancel_Click(object sender, RoutedEventArgs e) { this.Result = false; this.Close(); e.Handled = true; } /********************* public static method **************************/ /// <summary> /// 提示错误消息 /// </summary> public static void Error(string mes, Window owner = null) { Show(EnumNotifyType.Error, mes, owner); } /// <summary> /// 提示普通消息 /// </summary> public static void Info(string mes, Window owner = null) { Show(EnumNotifyType.Info, mes, owner); } /// <summary> /// 提示警告消息 /// </summary> public static void Warning(string mes, Window owner = null) { Show(EnumNotifyType.Warning, mes, owner); } /// <summary> /// 提示询问消息 /// </summary> public static bool Question(string mes, Window owner = null) { return Show(EnumNotifyType.Question, mes, owner); } /// <summary> /// 显示提示消息框, /// owner指定所属父窗体,默认参数值为null,则指定主窗体为父窗体。 /// </summary> private static bool Show(EnumNotifyType type, string mes, Window owner = null) { var res = true; Application.Current.Dispatcher.Invoke(new Action(() => { MessageBoxX nb = new MessageBoxX(type, mes) { Title = type.GetDescription() }; nb.Owner = owner ?? Application.Current.MainWindow; nb.ShowDialog(); res = nb.Result; })); return res; } /// <summary> /// 通知消息类型 /// </summary> public enum EnumNotifyType { [Description("错误")] Error, [Description("警告")] Warning, [Description("提示信息")] Info, [Description("询问信息")] Question, } }