WPF 消息提示 类似toast方式

WPF里面的消息提示一般都是MessageBox.Show(),这种样式不是很好看,所以就想办法重新搞了一个类似弹出消息的功能。原理很简单,就是弹出一个新窗体,然后等几秒窗体自动关闭。

先上效果图:

新建一个MsgHelper.cs类,然后全局可以调用。

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代码如下:

XML 复制代码
<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

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代码如下:

XML 复制代码
<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

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

相关推荐
friklogff1 小时前
【无标题】云端之C#:全面解析6种云服务提供商的SDK
开发语言·flask·c#
c#上位机2 小时前
C#事件的用法
java·javascript·c#
chnyi6_ya2 小时前
一些写leetcode的笔记
笔记·leetcode·c#
IT规划师3 小时前
C#|.net core 基础 - 扩展数组添加删除性能最好的方法
c#·.netcore·数组
时光追逐者3 小时前
分享6个.NET开源的AI和LLM相关项目框架
人工智能·microsoft·ai·c#·.net·.netcore
friklogff4 小时前
【C#生态园】提升C#开发效率:深入了解自然语言处理库与工具
开发语言·c#·区块链
__water13 小时前
『功能项目』回调函数处理死亡【54】
c#·回调函数·unity引擎
__water13 小时前
『功能项目』眩晕图标显示【52】
c#·unity引擎·动画事件
__water13 小时前
『功能项目』第二职业法师的平A【57】
c#·unity引擎·魔法球伤害传递
__water16 小时前
『功能项目』战士的伤害型技能【45】
c#·unity引擎·战士职业伤害型技能