zoukankan      html  css  js  c++  java
  • WPF实战之一 桌面消息框(右下角消息弹出框)

    此版本是根据别人的项目改造的,记录下笔记

    原文:https://blog.csdn.net/catshitone/article/details/75089069

    一、即时弹出

    1.创建弹出框

    新建一个100*300的WPF页面NotificationWindow.Xaml

     <Grid Background="AliceBlue">
            <Button Click="Button_Click" Content="Close" HorizontalAlignment="Left" Margin="225,0,0,0" VerticalAlignment="Top" Width="75"/>
            <TextBlock x:Name="tbTitle" HorizontalAlignment="Left" Margin="31,16,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
            <TextBlock x:Name="tbContent" HorizontalAlignment="Left" Margin="31,42,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/> 
        </Grid>

    后置页代码

     public partial class NotificationWindow : Window
        {
            public double TopFrom
            {
                get; set;
            }
            public NotificationWindow()
            {
                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;
                }
                NotificationWindow self = sender as NotificationWindow;
                if (self != null)
                {
                    self.UpdateLayout();
                    SystemSounds.Asterisk.Play();//播放提示声
    
                    double right = SystemParameters.WorkArea.Right;//工作区最右边的值
                    self.Top = self.TopFrom - self.ActualHeight;
                    DoubleAnimation animation = new DoubleAnimation();
                    animation.Duration = new Duration(TimeSpan.FromMilliseconds(500));//NotifyTimeSpan是自己定义的一个int型变量,用来设置动画的持续时间
                    animation.From = right;
                    animation.To = right - self.ActualWidth;//设定通知从右往左弹出
                    self.BeginAnimation(Window.LeftProperty, animation);//设定动画应用于窗体的Left属性
    
                    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);
            }
        }

    2.弹出消息

    在主页面创建一个弹出按钮,事件如下

    private void Button_Click(object sender, RoutedEventArgs e)
            {
                i++;
                NotifyData data = new NotifyData();
                data.Title = "这是标题:" + i;
                data.Content = "这是手动内容 ";
                showNotify(data);
            }
    
            private void showNotify(NotifyData data)
            { 
                NotificationWindow dialog = new NotificationWindow();//new 一个通知
                dialog.Closed += Dialog_Closed;
                dialog.TopFrom = GetTopFrom();
                dialog.DataContext = data;//设置通知里要显示的数据
                dialog.Show();
    
                _dialogs.Add(dialog);
            }

    二、定时弹出

    1.创建弹出框

      和前面的第一步一样

    2.创建事件通知接口

    部分代码

     /// <summary>
        /// 事件通知接口
        /// </summary>
        public interface IEventNotify
        { 
            /// <summary>
            /// 事件通知
            /// </summary>
            void EventNotify(EventData eventData);
        }
         
        /// <summary>
        /// 事件数据实体
        /// </summary>
        public class EventData
        { 
            public EventNotifyType EventNotify { get; set; } 
    
            public object Data { get; set; } 
        }

    3.实现定时消息

    在消息管理类添加一个定时器,每隔3秒执行一次。

    在Timer_Elapsed中,定时获取最新数据

    public class NoticeManager : IDisposable
        {
            /// <summary>
            /// 定时器
            /// </summary>
            private readonly Timer _timer;
            public IMainEventCommnuicationHandler Handler { get; private set; }
             
            private int seconds = 1 * 3;
    
            public NoticeManager(IMainEventCommnuicationHandler handler)
            {
                Handler = handler;
                _timer = new Timer(seconds * 1000);
                _timer.Elapsed += Timer_Elapsed;
                _timer.Start();
                 
            }
    
            /// <summary>
            /// 定时事件
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private async void Timer_Elapsed(object sender, ElapsedEventArgs e)
            { 
                for (int i = 0; i < 3; i++)
                {
                    var notifyData = new NotifyData()
                    {
                        Title = "标题" + i,
                        Content = DateTime.Now.AddHours(i).ToString()
    
                    };
                    EventData eventData = new EventData()
                    {
                        EventNotify = EventNotifyType.New,
                        Data = notifyData
                    };
                    Handler.EventNotify(eventData);
                }
            }
             
            public void Dispose()
            {
                if (_timer != null)
                {
                    _timer.Stop();
                    _timer.Dispose();
                }
            }
        }

    4.弹出消息

    private NoticeManager noticeManager;
            private void Time_Click(object sender, RoutedEventArgs e)
            {
                if (noticeManager == null)
                {
                    noticeManager = new NoticeManager(this);
                    btnTime.Content = "暂停弹出"; 
                }
                else
                {
                    btnTime.Content = "定时弹出";
                    noticeManager.Dispose();
                }
            }
    
    
            public void EventNotify(EventData eventData)
            {
                if (eventData.EventNotify == EventNotifyType.New)
                {
                    var data = eventData.Data as NotifyData;
                    SendMessage(data);
                }
                else
                {
                    MessageBox.Show("其他定时消息");
                }
            }
    
            /// <summary>
            /// 发出通知
            /// </summary>
            /// <param name="data"></param>
            void SendMessage(NotifyData data)
            {
                //此处调用Invoke,否则会报错:“ 调用线程必须为 STA,因为许多 UI 组件都需要 ”。
                App.Current.Dispatcher.Invoke(() =>
                {
                    showNotify(data);
                });
            }

    事件通知时不能直接使用UI组件,否则会报错:“ 调用线程必须为 STA,因为许多 UI 组件都需要 ”。

    Dispatcher是一个线程控制器,反正你要控制线程里跑的东西,就要经过它。那么WPF里面,有个所谓UI线程,后台代码不能直接操作UI控件,需要控制,就要通过这个Dispatcher。

    参考:https://www.cnblogs.com/xinaixia/p/5706096.html

    demo下载:https://gitee.com/zmsofts/XinCunShanNianDaiMa/blob/master/NotificationDemoWPF.rar

  • 相关阅读:
    git的突出解决--git rebase之abort、continue、skip
    servlet中service() 和doGet() 、doPost() 学习笔记
    Spring IoC容器初始化过程学习
    浅探SpringMVC中HandlerExecutionChain之handler、interceptor
    常用路由命令
    路由配置命令
    cout 计算顺序问题
    第一次作业
    记录一个微信网页授权中不小心踩到的坑(Curl请求返回false)
    善用mysql中的FROM_UNIXTIME()函数和UNIX_TIMESTAMP()函数
  • 原文地址:https://www.cnblogs.com/xcsn/p/10597303.html
Copyright © 2011-2022 走看看