1. 程式人生 > >【轉】WPF自定義控制元件與樣式(13)-自定義窗體Window & 自適應內容大小訊息框MessageBox

【轉】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="&#xe62e;"/>
        <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="&#xe60d;" 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="&#xe62b;" 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="&#xe60a;" 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="&#xe62b;"></Setter>
                        </Trigger>
                        <Trigger Property="WindowState" Value="Normal">
                            <Setter Property="FIcon" TargetName="btnMax" Value="&#xe65b;"></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="&#xe62e;"/>
        <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="&#xe60d;" 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="&#xe62b;" 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="&#xe60a;" 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="&#xe62b;"></Setter>
                        </Trigger>
                        <Trigger Property="WindowState" Value="Normal">
                            <Setter Property="FIcon" TargetName="btnMax" Value="&#xe65b;"></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="&#xe608;" 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="&#xe61c;" 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="&#xe646;" Width="85" Height="30" CornerRadius="0" Margin="5,5,20,5" Click="btnOK_Click">確定</local:FButton>
                <local:FButton x:Name="btnCancel" FIcon="&#xe60a;" 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,
        }
    }

 

原文地址:https://www.cnblogs.com/anding/p/5011981.html