WPF郵件群發工具開發 之 進度條(屬性改變通知機制)的實現


  前段時間,抽空用WPF做了個郵件群發工具;接下來想用兩三篇博客將開發過程中遇到的困惑和積累的經驗跟大家分享下,也算是拋磚引玉了,盡管對WinForm開發很熟悉,但畢竟它們之間差別比較大——從界面的呈現到內部的控制等。本篇博客看標題就可清楚,我要說的是進度條(屬性改變通知機制)的實現!
 

  進度條在WinForm中實現很容易,代碼如下:

 1         private void button1_Click(object sender, EventArgs e)
 2         {
 3             int num = 100;
 4             this.progressBar1.Maximum = num;
 5             for (int i = 0; i <= num; i = i + 10)
 6             {
 7                 this.progressBar1.Value = i;
 8                 Thread.Sleep(1000);
 9             }
10         }

  看似正常的邏輯,在WPF中卻沒有效果,其原因經測試和分析得出:應該是WinForm里控件和界面在同一個線程中,而WPF里它們不在同一個線程中

  現在切入正題,談談WPF中進度條(屬性改變通知機制)的實現——

    發送結果信息實體類

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Linq;
  4 using System.Text;
  5 using System.ComponentModel;
  6 
  7 namespace EmailBatchSend
  8 {
  9     /// <summary>
 10     /// 發送結果信息實體
 11     /// </summary>
 12     internal class SendResult : INotifyPropertyChanged
 13     {
 14         public event PropertyChangedEventHandler PropertyChanged;
 15 
 16         private string _progressBarNumShow = string.Empty;
 17         /// <summary>
 18         /// 進度條數字顯示
 19         /// </summary>
 20         public string ProgressBarNumShow
 21         {
 22             get
 23             {
 24                 return this._progressBarNumShow;
 25             }
 26             set
 27             {
 28                 this._progressBarNumShow = value;
 29                 OnPropertyChanged("ProgressBarNumShow");
 30             }
 31         }
 32 
 33         private string _sendResultMes = string.Empty;
 34         /// <summary>
 35         /// 發送結果消息
 36         /// </summary>
 37         public string SendResultMes
 38         {
 39             get
 40             {
 41                 return this._sendResultMes;
 42             }
 43             set
 44             {
 45                 this._sendResultMes = value;
 46                 OnPropertyChanged("SendResultMes");
 47             }
 48         }
 49 
 50         private string _sendFailEmails = string.Empty;
 51         /// <summary>
 52         /// 發送失敗的結果消息
 53         /// </summary>
 54         public string SendFailEmails
 55         {
 56             get
 57             {
 58                 return this._sendFailEmails;
 59             }
 60             set
 61             {
 62                 this._sendFailEmails = value;
 63                 OnPropertyChanged("SendFailEmails");
 64             }
 65         }
 66 
 67         private int _currentSendNum;
 68         /// <summary>
 69         /// 當前正在發送的 第幾個
 70         /// </summary>
 71         public int CurrentSendNum
 72         {
 73             get
 74             {
 75                 return this._currentSendNum;
 76             }
 77             set
 78             {
 79                 this._currentSendNum = value;
 80                 OnPropertyChanged("CurrentSendNum");
 81             }
 82         }
 83 
 84         private bool _sendControlIsEnabled = true;
 85         /// <summary>
 86         /// 發送郵件 控件是否可用
 87         /// </summary>
 88         public bool SendControlIsEnabled {
 89             get
 90             {
 91                 return this._sendControlIsEnabled;
 92             }
 93             set
 94             {
 95                 this._sendControlIsEnabled = value;
 96                 OnPropertyChanged("SendControlIsEnabled");
 97             }
 98         }
 99 
100         private void OnPropertyChanged(string propertyName)
101         {
102             if (this.PropertyChanged != null)
103                 this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
104         }
105     }
106 }

    界面上的使用

                                                                                                圖001

    通過上面的代碼,可以看出SendResult類實現了INotifyPropertyChanged——此接口的用途是向客戶端發出某一屬性值已更改的通知,這個接口的定義很簡單,如下:

 1 namespace System.ComponentModel
 2 {
 3     // 摘要:
 4     //     向客戶端發出某一屬性值已更改的通知。
 5     public interface INotifyPropertyChanged
 6     {
 7         // 摘要:
 8         //     在更改屬性值時發生。
 9         event PropertyChangedEventHandler PropertyChanged;
10     }
11 }

    此接口中只有一個PropertyChanged事件的定義,顧名思義:此事件會在屬性值發生改變時被觸發調用,且不需要實現,我比較好奇其內部的具體實現。重點看圖001中的紅色和紫色區域,通過{Binding 屬性名}的方式分別設置了進度條的當前值和發送按鈕的可用狀態,而{Binding 屬性名}的用法在WPF中很普遍,其使用有點兒類似於WebForm中的數據綁定控件中的<%#Eval("屬性名")>,既然是類似,那同樣的還需要給控件設置一個類似DataSource的東東——使控件的數據綁定和具體的數據對象關聯起來,才能實現相應的功能。

1 SendResult sendResult = new SendResult();
2 this.progressBar.DataContext = sendResult;

  上面的代碼就相當於是設置progressBar的數據源,只不過在WPF中它有另外一個名稱叫:DataContext 數據上下文,幾乎所有的WPF控件都有DataContext此屬性,即都支持數據綁定。

  到這里,進度條的實現已OK,效果圖如下:

  因為對WPF根本談不上精通,如果有錯解的地方,希望大家能指出或談下自己的看法,感興趣的朋友,可以留言相互交流學習!


免責聲明!

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



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