基于WPF简单实现Meesage消息提醒

 更新时间:2023年07月05日 11:23:10   作者:WPF开发者  
这篇文章主要介绍了如何利用WPF简单实现Meesage消息提醒,文中的示例代码讲解详细,对我们学习或工作有一定帮助,需要的可以参考一下

WPF 简单实现 Meesage 消息提醒

框架使用.NET4 至 .NET6

Visual Studio 2022;

实现方式通过获取当前焦点的 Window 然后对它添加装饰器,将 Meesage 内部添加 ListBox 用作记录显示消息。

新建装饰器 MessageAdorner.cs 提供一个公共方法 PushMessage 提供可传参数

  • message 消息文本,居中显示从 Y 轴 0 方向屏幕下添加。
  • MessageBoxImage 消息类型枚举
  • 消息添加到 ListBox 集合中后,使用 DispatcherTimer 用来记时关闭 MessageItem

新建 MessageItem.cs 基础 ListBoxItem 用来展示每条 Meesage 消息

添加一个依赖属性 MessageType 枚举,用来区分显示的 Icon 与文本字体颜色

新建 MessageItem.xaml 的模板

对 EventTrigger Loaded 添加动画 ScaleY 从 0 到 1

新建 Message.cs 帮助类实现全局方便使用

添加静态方法 PushMessage 判断装饰器是否为空,如果为空则创建装饰,如果不为空则调用装饰器内部 PushMessage 方法

下期会写一个增加关闭消息,消息谈出,文本居中等。

此项目使用了 WPFDevelopers 的引用

实现代码

1)新增 MessageItem.cs 代码如下:

using System.Windows;
using System.Windows.Controls;
namespace MessageSample
{
    public class MessageItem : ListBoxItem
    {
        public MessageBoxImage MessageType
        {
            get { return (MessageBoxImage)GetValue(MessageTypeProperty); }
            set { SetValue(MessageTypeProperty, value); }
        }
        public static readonly DependencyProperty MessageTypeProperty =
            DependencyProperty.Register("MessageType", typeof(MessageBoxImage), typeof(MessageItem), new PropertyMetadata(MessageBoxImage.Information));
    }
}

2)新增 MessageAdorner.cs 代码如下:

public class MessageAdorner : Adorner
    {
        private ListBox listBox;
        private UIElement _child;
        private FrameworkElement adornedElement;
        public MessageAdorner(UIElement adornedElement) : base(adornedElement)
        {
            this.adornedElement = adornedElement as FrameworkElement;
        }
        public void PushMessage(string message, MessageBoxImage type = MessageBoxImage.Information)
        {
            if (listBox == null)
            {
                listBox = new ListBox() { Style = null ,BorderThickness = new Thickness(0) ,Background = Brushes.Transparent};
                Child = listBox;
            }
            var item = new MessageItem{ Content = message , MessageType = type};
            var timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(10);
            timer.Tick += (sender, e) =>
            {
                listBox.Items.Remove(item);
                timer.Stop();
            };
            listBox.Items.Insert(0,item);
            timer.Start();
        }
        public UIElement Child
        {
            get => _child;
            set
            {
                if (value == null)
                {
                    RemoveVisualChild(_child);
                    _child = value;
                    return;
                }
                AddVisualChild(value);
                _child = value;
            }
        }
        protected override int VisualChildrenCount
        {
            get
            {
                return _child != null ? 1 : 0;
            }
        }
        protected override Size ArrangeOverride(Size finalSize)
        {
            var x = (adornedElement.ActualWidth - _child.DesiredSize.Width) / 2;
            _child.Arrange(new Rect(new Point(x, 0), _child.DesiredSize));
            return finalSize;
        }
        protected override Visual GetVisualChild(int index)
        {
            if (index == 0 && _child != null) return _child;
            return base.GetVisualChild(index);
        }
    }

3)新增 Message.cs 代码如下:

public static class Message
    {
        private static MessageAdorner messageAdorner;
        public static void PushMessage( string message, MessageBoxImage type = MessageBoxImage.Information)
        {
            if (messageAdorner != null)
            {
                messageAdorner.PushMessage(message, type);
                return;
            }
            Window win = null;
            if (Application.Current.Windows.Count > 0)
            {
                win = Application.Current.Windows.OfType<Window>().FirstOrDefault(o => o.IsActive);
                if (win == null)
                    win = Application.Current.Windows.OfType<Window>().First(o => o.IsActive);
            }
            var layer = GetAdornerLayer(win);
            if (layer == null)
                throw new Exception("not AdornerLayer is null");
            messageAdorner = new MessageAdorner(layer);
            layer.Add(messageAdorner);
            messageAdorner.PushMessage(message, type);
        }
        static AdornerLayer GetAdornerLayer(Visual visual)
        {
            var decorator = visual as AdornerDecorator;
            if (decorator != null)
                return decorator.AdornerLayer;
            var presenter = visual as ScrollContentPresenter;
            if (presenter != null)
                return presenter.AdornerLayer;
            var visualContent = (visual as Window)?.Content as Visual;
            return AdornerLayer.GetAdornerLayer(visualContent ?? visual);
        }
    }

4)新增 MessageItem.xaml 代码如下:

 <Style BasedOn="{StaticResource WD.ControlBasicStyle}" TargetType="{x:Type local:MessageItem}">
                <Setter Property="Background" Value="{DynamicResource WD.BackgroundSolidColorBrush}" />
                <Setter Property="Width" Value="300" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type local:MessageItem}">
                            <wd:SmallPanel
                                Name="PART_SmallPanel"
                                Margin="4"
                                RenderTransformOrigin=".5,0">
                                <wd:SmallPanel.RenderTransform>
                                    <ScaleTransform />
                                </wd:SmallPanel.RenderTransform>
                                <Border
                                    Name="PART_Border"
                                    Background="{TemplateBinding Background}"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    CornerRadius="{Binding Path=(wd:ElementHelper.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
                                    Effect="{StaticResource WD.NormalShadowDepth}"
                                    SnapsToDevicePixels="True"
                                    UseLayoutRounding="True" />
                                <Border Padding="10">
                                    <DockPanel>
                                        <Path
                                            x:Name="PART_Path"
                                            Width="15"
                                            Height="15"
                                            Data="{StaticResource WD.InformationGeometry}"
                                            Fill="{DynamicResource WD.PrimaryNormalSolidColorBrush}"
                                            Stretch="Fill" />
                                        <TextBlock
                                            Grid.Row="1"
                                            Grid.Column="1"
                                            Margin="5,0"
                                            VerticalAlignment="Center"
                                            FontSize="{DynamicResource WD.NormalFontSize}"
                                            Foreground="{TemplateBinding Foreground}"
                                            Text="{TemplateBinding Content}"
                                            TextWrapping="Wrap" />
                                    </DockPanel>
                                </Border>
                            </wd:SmallPanel>
                            <ControlTemplate.Triggers>
                                <Trigger Property="MessageType" Value="Warning">
                                    <Setter TargetName="PART_Path" Property="Data" Value="{StaticResource WD.WarningGeometry}" />
                                    <Setter TargetName="PART_Path" Property="Fill" Value="{StaticResource WD.WarningSolidColorBrush}" />
                                    <Setter Property="Foreground" Value="{StaticResource WD.WarningSolidColorBrush}" />
                                </Trigger>
                                <Trigger Property="MessageType" Value="Error">
                                    <Setter TargetName="PART_Path" Property="Data" Value="{StaticResource WD.ErrorGeometry}" />
                                    <Setter TargetName="PART_Path" Property="Fill" Value="{StaticResource WD.DangerSolidColorBrush}" />
                                    <Setter Property="Foreground" Value="{StaticResource WD.DangerSolidColorBrush}" />
                                </Trigger>
                                <Trigger Property="MessageType" Value="Information">
                                    <Setter TargetName="PART_Path" Property="Data" Value="{StaticResource WD.InformationGeometry}" />
                                    <Setter TargetName="PART_Path" Property="Fill" Value="{StaticResource WD.SuccessSolidColorBrush}" />
                                    <Setter Property="Foreground" Value="{StaticResource WD.SuccessSolidColorBrush}" />
                                </Trigger>
                                <Trigger Property="MessageType" Value="Question">
                                    <Setter TargetName="PART_Path" Property="Data" Value="{StaticResource WD.QuestionGeometry}" />
                                    <Setter TargetName="PART_Path" Property="Fill" Value="{StaticResource WD.NormalSolidColorBrush}" />
                                    <Setter Property="Foreground" Value="{StaticResource WD.NormalSolidColorBrush}" />
                                </Trigger>
                                <EventTrigger RoutedEvent="Loaded">
                                    <BeginStoryboard>
                                        <Storyboard>
                                            <DoubleAnimation
                                                Storyboard.TargetName="PART_SmallPanel"
                                                Storyboard.TargetProperty="(UIElement.RenderTransform).(ScaleTransform.ScaleY)"
                                                From="0"
                                                To="1"
                                                Duration="0:0:0.2" />
                                            <DoubleAnimation
                                                Storyboard.TargetName="PART_SmallPanel"
                                                Storyboard.TargetProperty="Opacity"
                                                From="0.01"
                                                To="1"
                                                Duration="0:0:0.2" />
                                        </Storyboard>
                                    </BeginStoryboard>
                                </EventTrigger>
                                <Trigger SourceName="PART_SmallPanel" Property="Opacity" Value="0">
                                    <Setter Property="Visibility" Value="Collapsed" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

5)新增 示例 代码如下:

<wd:Window
    x:Class="MessageSample.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:local="clr-namespace:MessageSample"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
    Title="WPFDevelopers - Message"
    Width="800"
    Height="450"
    mc:Ignorable="d">
    <Grid>
        <StackPanel
            Grid.Row="1"
            HorizontalAlignment="Center"
            VerticalAlignment="Bottom"
            Orientation="Horizontal">
            <Button
                Click="AddButton_Click"
                Content="Info Message"
                Style="{StaticResource WD.SuccessPrimaryButton}"
                Tag="Info" />
            <Button
                Click="AddButton_Click"
                Content="Error Message"
                Style="{StaticResource WD.DangerPrimaryButton}"
                Tag="Error" />
            <Button
                Click="AddButton_Click"
                Content="Warning Message"
                Style="{StaticResource WD.WarningPrimaryButton}"
                Tag="Warning" />
            <Button
                Click="AddButton_Click"
                Content="Question Message"
                Style="{StaticResource WD.PrimaryButton}"
                Tag="Question" />
            <Button
                Click="AddButton_Click"
                Content="Very Long Message"
                Style="{StaticResource WD.SuccessPrimaryButton}"
                Tag="Long" />
        </StackPanel>
    </Grid>
</wd:Window>

6) 示例 代码如下:

using System.Windows;
using System.Windows.Controls;
namespace MessageSample
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void AddButton_Click(object sender, RoutedEventArgs e)
        {
            var btn = sender as Button;
            switch (btn.Tag)
            {
                case "Info":
                    Message.PushMessage("这是一条成功消息", MessageBoxImage.Information);
                    break;
                case "Error":
                    Message.PushMessage("这是一条错误消息", MessageBoxImage.Error);
                    break;
                case "Warning":
                    Message.PushMessage("这是一条警告消息", MessageBoxImage.Warning);
                    break;
                case "Question":
                    Message.PushMessage("这是一条询问消息", MessageBoxImage.Question);
                    break;
                default:
                    Message.PushMessage("这是一条很长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长长消息", MessageBoxImage.Information);
                    break;
            }
        }
    }
}

效果图

以上就是基于WPF简单实现Meesage消息提醒的详细内容,更多关于WPF Meesage消息提醒的资料请关注脚本之家其它相关文章!

相关文章

  • C#制作多线程处理强化版网络爬虫

    C#制作多线程处理强化版网络爬虫

    这篇文章主要介绍了C#制作多线程处理强化版网络爬虫的相关代码,有想学习C#多线程编程的小伙伴可以参考下
    2016-09-09
  • 简单实现C#异步操作

    简单实现C#异步操作

    这篇文章主要为大家详细介绍了C#简单实现异步操作的方法,通过BeginInvoke、EndInvoke的方式实现异步编程,感兴趣的小伙伴们可以参考一下
    2016-02-02
  • C#实现的中国移动官网手机号码采集器

    C#实现的中国移动官网手机号码采集器

    这篇文章主要介绍了C#实现的中国移动官网手机号码采集器,本文先是采集号码入库,同时给出了筛选各类靓号的SQL语句,需要的朋友可以参考下
    2014-10-10
  • C#导出数据到Excel文件的方法

    C#导出数据到Excel文件的方法

    这篇文章主要介绍了C#导出数据到Excel文件的方法,涉及C#操作Excel的相关技巧,非常具有实用价值,需要的朋友可以参考下
    2015-04-04
  • C#实现将数组内元素打乱顺序的方法

    C#实现将数组内元素打乱顺序的方法

    这篇文章主要介绍了C#实现将数组内元素打乱顺序的方法,涉及C#数组遍历及随机数操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-08-08
  • C#操作word的方法示例

    C#操作word的方法示例

    这篇文章主要介绍了C#操作word的方法,结合实例形式分析了C#针对word文档的读取、写入、保存等相关操作技巧,需要的朋友可以参考下
    2017-05-05
  • C#窗体实现点餐系统

    C#窗体实现点餐系统

    这篇文章主要为大家详细介绍了C#窗体实现点餐系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C# 导出Excel的6种简单方法实现

    C# 导出Excel的6种简单方法实现

    C# 导出 Excel 的6种简单方法:数据表导出到 Excel,对象集合导出到 Excel,数据库导出到 Excel,微软网格控件导出到 Excel,数组导出到 Excel,CSV 导出到 Excel,你都会了吗?需要的朋友们下面随着小编来一起学习学习吧
    2019-09-09
  • C#使用Log4.net记录日志文件

    C#使用Log4.net记录日志文件

    这篇文章介绍了C#使用Log4.net记录日志文件的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • Unity利用XML制作一个简易的登录系统

    Unity利用XML制作一个简易的登录系统

    这篇文章主要介绍了如何在Unity中利用XML文件制作一个简易的登录系统,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-03-03

最新评论