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

  • 相关阅读:
    Win8系统 Python安装
    一些安卓开源框架整理
    Android 媒体键监听以及模拟媒体键盘的实现 demo
    android View 自动 GONE 问题
    Android 定时器TimerTask 简单使用
    关于Android studio 相对 eclipse 优点
    Java序列化与反序列化
    android shape的使用 边框
    Android Studio 修改 包名 package name
    Android WebView Long Press长按保存图片到手机
  • 原文地址:https://www.cnblogs.com/xcsn/p/10597303.html
Copyright © 2011-2022 走看看