WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

时间:2022-06-02 09:47:17

一.前言

  申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接。

  本文主要内容:

  • 自定义Window窗体样式;
  • 基于自定义窗体实现自定义MessageBox消息提示框;

二.自定义Window窗体样式

  自定义的Window窗体效果:

WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

  因为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 + + ;
//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就简单了,效果图:

WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBoxWPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框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,
}
}

附录:参考引用

WPF自定义控件与样式(1)-矢量字体图标(iconfont)

WPF自定义控件与样式(2)-自定义按钮FButton

WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式

WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox

WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu

WPF自定义控件与样式(10)-进度控件ProcessBar自定义样

WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现

WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

版权所有,文章来源:http://www.cnblogs.com/anding

个人能力有限,本文内容仅供学习、探讨,欢迎指正、交流。

WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox的更多相关文章

  1. 【转】WPF自定义控件与样式&lpar;13&rpar;-自定义窗体Window &amp&semi; 自适应内容大小消息框MessageBox

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等. 本文主要内容: 自定义Window窗体样式: 基于自定义窗体实现自定义MessageB ...

  2. WPF自定义控件与样式&lpar;2&rpar;-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 还是先看看效果 ...

  3. 【转】WPF自定义控件与样式&lpar;2&rpar;-自定义按钮FButton

    一.前言.效果图 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等 还是先看看效果图吧:   定义Button按钮名称叫FButton,主要是集成了 ...

  4. WPF自定义控件与样式&lpar;1&rpar;-矢量字体图标&lpar;iconfont&rpar;

    一.图标字体 图标字体在网页开发上运用非常广泛,具体可以网络搜索了解,网页上的运用有很多例子,如Bootstrap.但在C/S程序中使用还不多,字体图标其实就是把矢量图形打包到字体文件里,就像使用一般 ...

  5. WPF自定义控件与样式&lpar;15&rpar;-终结篇 &amp&semi; 系列文章索引 &amp&semi; 源码共享

    系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与样式(3)-TextBox & Ric ...

  6. WPF自定义控件与样式&lpar;14&rpar;-轻量MVVM模式实践

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. MVVM是WPF中一个非 ...

  7. WPF自定义控件与样式&lpar;15&rpar;-终结篇

    原文:WPF自定义控件与样式(15)-终结篇 系列文章目录  WPF自定义控件与样式(1)-矢量字体图标(iconfont) WPF自定义控件与样式(2)-自定义按钮FButton WPF自定义控件与 ...

  8. WPF自定义控件与样式&lpar;4&rpar;-CheckBox&sol;RadioButton自定义样式

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: Che ...

  9. WPF自定义控件与样式&lpar;5&rpar;-Calendar&sol;DatePicker日期控件自定义样式及扩展

    一.前言 申明:WPF自定义控件与样式是一个系列文章,前后是有些关联的,但大多是按照由简到繁的顺序逐步发布的等,若有不明白的地方可以参考本系列前面的文章,文末附有部分文章链接. 本文主要内容: 日历控 ...

随机推荐

  1. mvc url 伪静态

    WebConfig配置 <system.webServer> <validation validateIntegratedModeConfiguration="false& ...

  2. ios开发——实用技术篇Swift篇&amp&semi;拍照

    拍照 // MARK: - 拍照 func fromPhotograph() { if UIImagePickerController.isSourceTypeAvailable(.Camera) { ...

  3. 用CImage类来显示PNG、JPG等图片

    系统环境:Windows 7软件环境:Visual Studio 2008 SP1本次目的:实现VC单文档.对话框程序显示图片效果 CImage 是VC.NET中定义的一种MFC/ATL共享类,也是A ...

  4. leetcode Generate Parentheses python

    # 解题思路:列举出所有合法的括号匹配,使用dfs.如果左括号的数量大于右括号的数量的话,就不能产生合法的括号匹配class Solution(object): def generateParenth ...

  5. java多线程学习(两)——创建一个线程

    一个.java创建两个线程的方法 1.从java.lang.Thread派生一个新类线程类,其覆盖run()方法 2.实现Runnable接口.重载Runnable接口中的run()方法. 使用Thr ...

  6. uva 1556 - Disk Tree&lpar;特里&rpar;

    题目连接:uva 1556 - Disk Tree 题目大意:给出N个文件夹关系,然后依照字典序输出整个文件文件夹. 解题思路:以每一个文件夹名作为字符建立一个字典树就可以,每一个节点的关系能够用ma ...

  7. 第三方登录SDK

    紧接着上次的第三方登录文档,这一波又来了. 一.使用qq登录https://connect.qq.com/ 首次登录的话会跳转到应用开发者注册,自己测试的话选择个人.下面的各项自己按真实情况填写. 注 ...

  8. Java日志框架:slf4j作用及其实现原理

    简单回顾门面模式 slf4j是门面模式的典型应用,因此在讲slf4j前,我们先简单回顾一下门面模式, 门面模式,其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用.用一 ...

  9. springboot~mybatis里localdatetime序列化问题

    问题起因 主要是使用mybatis作为ORM之后,返回的对象为Map,然后对于数据库的datetime,datestamp类型返回为时间戳而不是标准的时间,这个问题解决方案有两种,大叔分析一下: 在m ...

  10. group by 显示

    public static void PrintPersons()         {             //准备数据             DataTable dt = new DataTa ...