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秒。