WPF里面的消息提示一般都是MessageBox.Show(),这种样式不是很好看,所以就想办法重新搞了一个类似弹出消息的功能。原理很简单,就是弹出一个新窗体,然后等几秒窗体自动关闭。
先上效果图:
新建一个MsgHelper.cs类,然后全局可以调用。
using System.Windows;
using System.Windows.Threading;
namespace WpfApp1;
public static class MsgHelper
{
/// <summary>
/// 弹出消息
/// </summary>
/// <param name="msg"></param>
/// <param name="msgState"></param>
public static void ShowMsg(string msg, MsgState msgState = MsgState.Info)
{
//调用之前先关闭可能已打开的窗口
CloseWindow();
_timer = new DispatcherTimer();
_timer.Interval = TimeSpan.FromSeconds(2);
_timer.Tick += _timer_Tick;
_timer.Start();
var mainWindow = Application.Current.Windows.OfType<MainWindow>().FirstOrDefault();
var window = new MsgWindow(msg, msgState) { Owner = mainWindow };
window.Show();
}
/// <summary>
/// 定时器
/// </summary>
static DispatcherTimer _timer;
private static void _timer_Tick(object? sender, EventArgs e)
{
CloseWindow();
}
/// <summary>
/// 关闭窗体
/// </summary>
public static void CloseWindow()
{
if (_timer != null)
{
_timer.Stop();
}
var msgWindow = Application.Current.Windows.OfType<MsgWindow>().FirstOrDefault();
msgWindow?.Close();
}
/// <summary>
/// 消息类型
/// </summary>
public enum MsgState
{
Info,
Success,
Error
}
}
新建MsgWindow窗体,用于显示消息。样式可以自己写的好看一点,我这里就没做美化了。
MsgWindow.xaml代码如下:
<Window x:Class="WpfApp1.MsgWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MsgWindow" Loaded="Window_Loaded" Height="40" Width="300"
Background="Transparent"
ShowInTaskbar="False" WindowStyle="None" AllowsTransparency="True"
WindowStartupLocation="CenterScreen" >
<Border BorderBrush="DarkBlue" BorderThickness="1">
<Grid Background="White" Name="grid" >
<TextBlock Text="" VerticalAlignment="Center" HorizontalAlignment="Center" Name="txtMsg" Margin="5"></TextBlock>
</Grid>
</Border>
</Window>
MsgWindow.xaml.cs
using System.Windows;
using System.Windows.Media;
using static WpfApp1.MsgHelper;
namespace WpfApp1
{
/// <summary>
/// MsgWindow.xaml 的交互逻辑
/// </summary>
public partial class MsgWindow : Window
{
private string _msg = "";
private MsgState _msgState = MsgState.Info;
public MsgWindow(string msg, MsgState msgState)
{
InitializeComponent();
_msg = msg;
_msgState = msgState;
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
txtMsg.Text = _msg;
switch (_msgState)
{
case MsgState.Info:
grid.Background = new SolidColorBrush(Colors.LightGray);
break;
case MsgState.Success:
grid.Background = new SolidColorBrush(Colors.Green);
txtMsg.Foreground = new SolidColorBrush(Colors.White);
break;
case MsgState.Error:
grid.Background = new SolidColorBrush(Colors.Red);
txtMsg.Foreground = new SolidColorBrush(Colors.White);
break;
}
}
}
}
然后在调用。我这里是在主窗体里面调用的,其他窗体里调用是一样的。
MainWindow.xaml代码如下:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Content="info" Width="100" Height="100" Click="ButtonBase_OnClick" Tag="info"></Button>
<Button Content="success" Grid.Row="0" Grid.Column="1" Width="100" Height="100" Tag="success" Click="ButtonBase_OnClick"></Button>
<Button Content="error" Grid.Row="0" Grid.Column="2" Width="100" Height="100" Tag="error" Click="ButtonBase_OnClick"></Button>
</Grid>
</Window>
MainWindow.xaml.cs
using System.Windows;
using System.Windows.Controls;
using static WpfApp1.MsgHelper;
namespace WpfApp1;
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
if (sender is Button btn)
{
var tag = btn.Tag.ToString();
var infoType = MsgState.Info;
switch (tag)
{
case "info":
infoType = MsgState.Info;
break;
case "success":
infoType = MsgState.Success;
break;
case "error":
infoType = MsgState.Error;
break;
default:
break;
}
MsgHelper.ShowMsg(DateTime.Now.ToString(), infoType);
}
}
}
这里要注意一个问题,在调用ShowMsg()方法,有个owner要指定,我这里给的是主窗体,因为主窗体一般不会被关闭,如果是在其他窗体里面,可以把这个方法再加个参数,然后调用的地方传个this就可以。
还有就是MsgWindow的窗体的ShowInTaskbar 要设置为false,不然当鼠标移到任务栏的程序图标时,会显示有两个窗体。
也可以将MsgWindow的Topmost设置为true,这样就肯定是在最上层,但是这个最上层是所有软件的最上层,感觉不是很好。可以根据自己的需求来。
超时时间自己设置,我这里设置的是2秒。