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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM