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消息提醒的资料请关注软件开发网其它相关文章!