1.先上效果图:

2.1t提示框界面。 主窗口界面没什么内容,就放了一个触发按钮。先绘制通知窗口(一个关闭按钮,俩个文本控件),可以设置下resizemode=”noresize” windowstyle=”none”   topmost=”true”,

去掉窗口标题,并使提示窗口始终处于最上层。

<border borderthickness="1" borderbrush="black">
    <grid>
        <grid.rowdefinitions>
            <rowdefinition height="6*" />
            <rowdefinition />
        </grid.rowdefinitions>
        <grid background="white">
            <button
                margin="5"
                horizontalalignment="right"
                verticalalignment="top"
                background="white"
                borderthickness="0"
                click="button_click"
                content=" × "
                fontsize="18" />
            <textblock
                x:name="tbtitle"
                margin="5"
                horizontalalignment="left"
                verticalalignment="top"
                fontsize="16"
                text="textblock"
                textwrapping="wrap" />
            <textblock
                x:name="tbcontent"
                margin="20,40,0,0"
                horizontalalignment="left"
                verticalalignment="top"
                fontsize="16"
                text="textblock"
                textwrapping="wrap" />
        </grid>
        <grid grid.row="2" background="#f0f0f0" />
    </grid>
    </border>

2.2主窗口后台代码。

notifydata类是弹出窗口的推送消息。
list<window1>计算高度时,如果窗口关闭,窗口就会从list中移除。
gettopfrom负责计算弹出窗口距离屏幕顶端的高度。
button_click 传递消息,弹出窗口。
 
   class notifydata
    {
        public string title { get; set; }
        public string content { get; set; }
    }

 

   public partial class mainwindow : window
    {
        int i = 0;
        public static list<window1> _dialogs = new list<window1>();
        public mainwindow()
        {
            initializecomponent();
        }
     
        private void button_click(object sender, routedeventargs e)
        {
            i++;
            notifydata data = new notifydata();
            data.title = "提示";       
            data.content = "xxx余额不足,xxx余额不足,xxx余额不足,xxx余额不足" + i;
            window1 dialog = new window1();//new 一个通知  
            dialog.closed += dialog_closed;
            dialog.topfrom = gettopfrom();
            dialog.datacontext = data;//设置通知里要显示的数据            
            dialog.show();
            _dialogs.add(dialog);
        }
        private void dialog_closed(object sender, eventargs e)
        {
            var closeddialog = sender as window1;
            _dialogs.remove(closeddialog);
        }
        double gettopfrom()
        {
            //屏幕的高度-底部taskbar的高度。
            double topfrom = system.windows.systemparameters.workarea.bottom - 10;
            bool iscontinuefind = _dialogs.any(o => o.topfrom == topfrom);
            while (iscontinuefind)
            {
                topfrom = topfrom - 160;//此处100是notifywindow的高 160-100剩下的10  是通知之间的间距
                iscontinuefind = _dialogs.any(o => o.topfrom == topfrom);
            }
            if (topfrom <= 0)
                topfrom = system.windows.systemparameters.workarea.bottom-10;
            return topfrom;
        }
    }

2.3消息提醒窗后台代码

notificationwindow_loaded 接收传过来的内容topfrom和notifydata,然后确定弹出窗口位置,并在5s后关闭窗口。
button_click 关闭窗口
 public partial class window1 : window
    {
        public double topfrom
        {
            get; set;
        }

        public window1()
        {
            initializecomponent();
            this.loaded += notificationwindow_loaded;
        }

        private void notificationwindow_loaded(object sender, routedeventargs e)
        {
           
           notifydata data = this.datacontext as notifydata;
            if (data != null)
            {
                tbcontent.text = data.content;
                tbtitle.text = data.title;
            }
            window1 self = sender as window1;
            if (self!=null)
            {
                double right=systemparameters.workarea.right-10;//工作区最右边的值                        
                self.top = topfrom - 160;
                doubleanimation animation = new doubleanimation();
                animation.duration = new duration(timespan.frommilliseconds(500));
                animation.from = right;
                animation.to = right - self.actualwidth;
                self.beginanimation(window.leftproperty, animation);

                task.factory.startnew(delegate
                {
                    int seconds = 5;//通知持续5s后消失
                    system.threading.thread.sleep(timespan.fromseconds(seconds));
                    //invoke到主进程中去执行
                    this.dispatcher.invoke(delegate
                    {
                        animation = new doubleanimation();
                        animation.duration = new duration(timespan.frommilliseconds(500));
                        animation.completed += (s, a) => { self.close(); };//动画执行完毕,关闭当前窗体
                        animation.from = right - self.actualwidth;
                        animation.to = right;//通知从左往右收回
                        self.beginanimation(window.leftproperty, animation);
                    });
                });
            }
        }
        private void button_click(object sender, routedeventargs e)
        {
            double right = systemparameters.workarea.right;
            doubleanimation animation = new doubleanimation();
            animation.duration = new duration(timespan.frommilliseconds(500));
            animation.completed += (s, a) => { this.close(); };
            animation.from = right - this.actualwidth;
            animation.to = right;
            this.beginanimation(window.leftproperty, animation);
        }
    }

 3.源码下载地址

https://files-cdn.cnblogs.com/files/king10086/noticedemo.7z