基于.Net4.0实现 ToastNotification

Windows更新之路的特色之一就是消息提示由气泡变成了通知窗口,效果简直不要太好。最近公司有这方面的需求,需要在xp,win7系统上给出提示,由此做了一个仿win10的ToastNotification,给出代码供大家参考:

开源库中也有很多的ToastNotification实现,但是我发现几乎都是基于一个应用的:当你打开一个应用,弹出的界面会向上堆叠,但是当你打开多个应用程序,弹出的界面会重叠在一起。后来通过共享内存文件的方式使他们互相通知我已经画到哪里了(主要是没用过进程间通讯,学习一下,哈哈)

效果图:

支持

·WPF

·WINFORM

·控制台程序

·显示界面可自定义

·自由控制动画

原理:

原理非常简单:

消息界面是wpf窗口,在窗口的Loaded和Closing事件添加滑入滑出动画:

 view.Loaded += OverrideLoaded;
view.ShowInTaskbar = false;
if (!view.Options.IsAutoClose)
{
view.Closing += OverrideClosing;
}

Loaded函数中的动画

  animation.Duration = notifier.Options.AnamitionDurationTime;
animation.From = notifier.Options.RightFrom;
animation.To = notifier.Options.RightTo; notifier.BeginAnimation(Window.LeftProperty, animation); if (notifier.Options.IsAutoClose)
{
Task.Factory.StartNew(delegate
{
int seconds = notifier.Options.AutoCloseShowTimeMS;
System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(seconds));
notifier.Dispatcher.Invoke(new Action(() =>
{
{
animation = new DoubleAnimation();
animation.Duration = notifier.Options.AnamitionDurationTime;
animation.Completed += (s, a) =>
{
notifier.CloseFun();
};
animation.From = notifier.Options.RightTo;
animation.To = notifier.Options.RightFrom;
notifier.BeginAnimation(Window.LeftProperty, animation);
}
}));
});
}

Closing

    DoubleAnimation animation = new DoubleAnimation();
animation.Duration = notifier.Options.AnamitionDurationTime;
animation.Completed += (s, a) => { notifier.Closing -= OverrideClosing;};
animation.From = notifier.Options.RightTo;
animation.To = notifier.Options.RightFrom;
notifier.BeginAnimation(Window.LeftProperty, animation);

需要注意的是在控制台程序中,由于没有消息循环,你需要将窗口Showdialog()

(大约是这样,类似于控制台程序的App.Run(window)没有消息循环而无法通知)

用法:

封装了几个接口,可以直接用,效果如效果图:

private void ButtonWarn_Click(object sender, RoutedEventArgs e)
{
Notifier.ShowWarn(Header.Text, GetString(), IsAutoClose.IsChecked == null ? false : (bool)IsAutoClose.IsChecked, int.Parse(Time.Text));
} private void ButtonSuccess_Click(object sender, RoutedEventArgs e)
{
Notifier.ShowSuccess(Header.Text, GetString(), IsAutoClose.IsChecked == null ? false : (bool)IsAutoClose.IsChecked, int.Parse(Time.Text));
} private void ButtonError_Click(object sender, RoutedEventArgs e)
{
Notifier.ShowError(Header.Text, GetString(), IsAutoClose.IsChecked == null ? false : (bool)IsAutoClose.IsChecked, int.Parse(Time.Text));
}

自定义窗口只需要继承NotifierViewBase,设计好样式就好了,然后调用Notifier.ShowView(NotifierViewBase view, ShowOptions options)

<baseView:NotifierViewBase x:Class="ToastNotification_Demo.CuttomView"
xmlns:baseView="clr-namespace:ToastNotification.Base;assembly=ToastNotification"
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:ToastNotification_Demo" mc:Ignorable="d"
Height="150" Width="500" Topmost="True" AllowsTransparency="True" Background="Transparent" WindowStyle="None">
<Grid>
<Label FontSize="72">Custom View</Label>
</Grid>
</baseView:NotifierViewBase>

介绍一下ShowOptions 类,里面主要是动画效果的属性,可以ShowView的时候传进去:

/// <summary>
/// 是否播放提示音
/// </summary>
public bool IsEnabledSounds { get; set; } = true;
/// <summary>
/// 是否自动关闭
/// </summary>
public bool IsAutoClose { get; set; } = true;
/// <summary>
/// 配合IsAutoClose,window显示时间
/// </summary>
public int AutoCloseShowTimeMS { get; set; } = 5000;
/// <summary>
/// 窗口显示位置(一般情况下不需要设置)
/// </summary>
public double NotifierTop { get; set; } = double.NaN;
/// <summary>
/// 窗口显示位置(动画初始位置)(一般情况下不需要设置)
/// </summary>
public double RightFrom { get; set; } = double.NaN;
/// <summary>
/// 窗口显示位置(动画结束位置)(一般情况下不需要设置)
/// </summary>
public double RightTo { get; set; } = double.NaN;
/// <summary>
/// 动画执行时间
/// </summary>
public Duration AnamitionDurationTime { get; set; } = new Duration(TimeSpan.FromMilliseconds(500));
/// <summary>
/// 是否是固定大小(W:300 h:150),否则为自适应大小
/// </summary>
public bool IsFixedSizeOrContentToWH { get; set; } = true;
/// <summary>
/// FixedSize时的高度,默认150
/// </summary>
public Double Height { get; set; } = 150;
/// <summary>
/// FixedSize时的宽度,默认350
/// </summary>
public Double Width { get; set; } = 350;

Github code+Sample地址:

https://github.com/tiancai4652/WPF_StatusNotification

基于.Net4.0实现 ToastNotification的更多相关文章

  1. IdentityServer4客户端JWT解密实现(基于.net4.0)

    情景:公司项目基于.net4.0,web客户端实现单点登录需要自己解密id_token,对于jwt解密,.net提供了IdentityModel类库,但是4.0中该类库不可用,所以自己实现了解密方法. ...

  2. IIS Web服务扩展中添加ASP.NET4.0

    问题 服务器上安装了ASP.NET 4.0.30319组件,但是在IIS的Web服务扩展中并没有找到ASP.NET v4.0.30319这项,这导致基于.NET4.0开发的网页都无法正常浏览(404错 ...

  3. .Net4.0 任务(Task)[转]

    .Net4.0 任务(Task) 任务(Task)是一个管理并行工作单元的轻量级对象.它通过使用CLR的线程池来避免启动专用线程,可以更有效率的利用线程池.System.Threading.Tasks ...

  4. “RazorEngine.Templating.TemplateCompilationException”类型的异常在 RazorEngine.NET4.0.dll 中发生,但未在用户代码中进行处理

    错误信息: "RazorEngine.Templating.TemplateCompilationException"类型的异常在 RazorEngine.NET4.0.dll 中 ...

  5. asp.net 项目Net4.0 在IE10、 IE 11 下出现 “__doPostBack”未定义 的解决办法

    我的项目中,服务器端是Windows Server2008 64位,.net版本是4.0,也遇到了树形结构控件.DropDownList控件等不能调用服务器端代码.最后发现js报错. 错误信息:“__ ...

  6. 编译可在Nexus5上运行的CyanogenMod13.0 ROM(基于Android6.0)

    编译可在Nexus5上运行的CyanogenMod13.0 ROM (基于Android6.0) 作者:寻禹@阿里聚安全 前言 下文中无特殊说明时CM代表CyanogenMod的缩写. 下文中说的“设 ...

  7. IIS6.0添加上.net4.0后,以前的.net系统出现“服务器应用程序不可用”的错误提示解决办法

    把VS2010开发的网站.net4.0部署到Windows Server 2003的服务器上去, Windows Server 2003操作系统自带的为IIS 6.0,IIS 6.0一般只支持.NET ...

  8. 关于把.net 2.0的项目升级到.net4.0遇到的一些问题

    进入公司实习的的第一个项目又是是一个升级项目.这次升级的是一个c/s架构的项目. 大致介绍一下这个项目的结构客户端采用winform+devexpress商业控件开发的,数据库是用的oracle数据库 ...

  9. IIS运行.NET4.0配置

    IIS运行.NET4.0配置 “/CRM”应用程序中的服务器错误.配置错误说明: 在处理向该请求提供服务所需的配置文件时出错.请检查下面的特定错误详细信息并适当地修改配置文件. 分析器错误消息: 无法 ...

随机推荐

  1. error: Error trying to parse settings: Unexpected trailing characters in Packages\User\Preferences.sublime-settings:9:2 reloading settings Packages/User/Preferences.sublime-settings

    error: Error trying to parse settings: Unexpected trailing characters in Packages\User\Preferences.s ...

  2. SQL Join连接

    SQL 连接(Joins) SQL join 用于把来自两个或多个表的行结合起来. SQL JOIN SQL JOIN 子句用于把来自两个或多个表的行结合起来,基于这些表之间的共同字段. 最常见的 J ...

  3. 低价购买 (动态规划,变种最长下降子序列(LIS))

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  4. hdu1574 I Hate It (线段树,查询区间最大值)

    Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少. 这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟 ...

  5. 【Flutter学习】之动画实现原理浅析(一)

    一,动画介绍 动画对于App来说,非常的重要.很多App,正是因为有了动画,所以才会觉得炫酷.移动端的动画库有非常的多,例如iOS上的Pop.web端的animate.css.Android端的And ...

  6. delphi 监控文件系统

    elphi 监控文件系统 你是否想为你的Windows加上一双眼睛,察看使用者在机器上所做的各种操作(例如建立.删除文件:改变文件或目录名字)呢? 这里介绍一种利用Windows未公开函数实现这个功能 ...

  7. AcWing 215. 破译密码 (莫比乌斯反演)打卡

    达达正在破解一段密码,他需要回答很多类似的问题: 对于给定的整数a,b和d,有多少正整数对x,y,满足x<=a,y<=b,并且gcd(x,y)=d. 作为达达的同学,达达希望得到你的帮助. ...

  8. commonJs的运行时加载和es6的编译时加载

    参考 : https://www.cnblogs.com/jerrypig/p/8145206.html 1.commonJs的运行时加载 2.ES6编译时加载

  9. Docker Machine 管理-安装docker-machine(15)

    前面我们的实验环境中只有一个 docker host,所有的容器都是运行在这一个 host 上的.但在真正的环境中会有多个 host,容器在这些 host 中启动.运行.停止和销毁,相关容器会通过网络 ...

  10. SPOJ_QTREE系列题解

    QTREE4 #pragma comment(linker, "/STACK:102400000,102400000") //#include<bits/stdc++.h&g ...