基于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消息提醒的资料请关注脚本之家其它相关文章!

相关文章

  • 基于WPF实现视频封面查看器

    基于WPF实现视频封面查看器

    这篇文章主要为大家详细介绍了WPF如何实现视频封面查看器,文中的示例代码讲解详细,对我们学习或工作有一定帮助,感兴趣的小伙伴可以了解一下
    2022-11-11
  • C#实现汉字转汉语拼音的示例代码

    C#实现汉字转汉语拼音的示例代码

    这篇文章主要介绍了如何利用C#实现汉字转汉语拼音,文中的示例代码讲解详细,对我们学习C#有一定帮助,感兴趣的小伙伴可以跟随小编一起动手试一试
    2022-03-03
  • C#简单创建和删除目录的方法

    C#简单创建和删除目录的方法

    这篇文章主要介绍了C#简单创建和删除目录的方法,实例分析了C#使用CreateDirectory及Delete方法简单创建及删除目录的相关实现技巧,需要的朋友可以参考下
    2015-08-08
  • C#的字符串比较

    C#的字符串比较

    这篇文章主要介绍了c# 字符串操作的相关知识,文中讲解的非常详细,代码帮助大家更好的学习,感兴趣的朋友可以参考下,希望能给你带来帮助
    2021-07-07
  • C#多线程系列之多阶段并行线程

    C#多线程系列之多阶段并行线程

    本文详细讲解了C#多线程的多阶段并行线程,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-02-02
  • C#调用Python程序传参数获得返回值

    C#调用Python程序传参数获得返回值

    C# 调用 Python 程序有多种方式,本文主要介绍了4种方式,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • 一个状态机的实现

    一个状态机的实现

    本文主要介绍了C#实现一个状态机的思路与方法,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • C#获得MAC地址(网卡序列号)的实现代码

    C#获得MAC地址(网卡序列号)的实现代码

    这篇文章主要介绍了C#获得MAC地址的实现代码,需要的朋友可以参考下
    2014-02-02
  • C#类和结构详解

    C#类和结构详解

    本文详细讲解了C#中的类和结构,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-04-04
  • C#的通用DbHelper类(支持数据连接池)示例详解

    C#的通用DbHelper类(支持数据连接池)示例详解

    这篇文章主要介绍了C#的通用DbHelper类支持数据连接池,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-03-03

最新评论