C# PropertyChanged 事件-數據綁定


在.NET平台上,數據綁定是一項令人十分愉快的技術。利用數據綁定能減少代碼,簡化控制邏輯。

通常,可以將某個對象的一個屬性綁定到一個可視化的控件上,當屬性值改變時,控件上的顯示數據也隨之發生變化。要實現這一功能,只需要為自定義對象實現 INotifyPropertyChanged 接口即可。此接口中定義了 PropertyChanged 事件,我們只需在屬性值改變時觸發該事件即可。下面的例子說明如何綁定如何自定義可用於數據綁定的對象:

假設我們有自定義對象 CustomizedObject 和窗體上的 Label 控件 label1,想要將 CustomizedObject 的 Date 屬性和 label1.Text 關聯起來,Date 屬性值會在程序運行過程當中發生變化(例如點擊 Button 控件 button1),並且直接反映在 label1.Text 上。下面的代碼可以實現上述功能:

using System;

using System.ComponentModel;

using System.Windows.Forms;

 

namespace WindowsFormsApplication1

{

    public partial class Form1 : Form

    {

        private CustomizedObject myObject;

 

        public Form1()

        {

            InitializeComponent();

 

            // 初始化CustomizedObject對象

            myObject = new CustomizedObject { Date = DateTime.Now };

 

            // 綁定對象的屬性到label1

            label1.DataBindings.Add("Text", myObject, "Date");

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            // 點擊按鈕改變對象的屬性值

            myObject.Date = myObject.Date.AddDays(1);

        }

 

    }

 

    // 自定義對象 CustomizedObject 並實現 INotifyPropertyChanged 接口

    public class CustomizedObject : INotifyPropertyChanged

    {

        private DateTime dateValue;

 

        // 自定義一個 Date 屬性

        public DateTime Date

        {

            get { return dateValue; }

            set

            {

                dateValue = value;

                NotifyPropertyChanged("Date");

            }

        }

 

        #region INotifyPropertyChanged Members

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        // 添加一個觸發 PropertyChanged 事件的通用方法

        protected virtual void NotifyPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

         #endregion

    }

}

 

其實從上面的例子中可以學習到如何自定義事件,這在開發控件時十分有用且非常重要。通過觀察 INotifyPropertyChanged 接口可以知道它內部有一個成員,那就是:

event PropertyChangedEventHandler PropertyChanged;

而其中的 PropertyChangedEventHandler 實質上是一個委托,明白了這一點就可以自定義事件了。

現在,開始為 Form1 自定義事件 DateChanged (事件一般是定義在控件或組件中的,這里只是為了說明其過程而沒有重新定義一個控件),首先需要一個事件參數類型:

public class DateChangedEventArgs : EventArgs

{

    public DateTime OldValue { get; set; }

    public DateTime NewValue { get; set; }

}

聲明一個事件處理委托

public delegate void DateChangedHandler(object sender, DateChangedEventArgs e);

 

我們可以將事件直接添加到Form1的定義中,但有時為了代碼的通用性,可以將事件封裝到一個接口中,例如:

public interface IDateChanged

{

    event DateChangedHandler DateChanged;

}

然后我們為Form1實現 IDateChanged 接口,並在button1點擊時觸發該事件。以下是完整代碼:

using System;

using System.ComponentModel;

using System.Windows.Forms;

 

namespace WindowsFormsApplication1

{

    public partial class Form1 : Form, IDateChanged

    {

        private CustomizedObject myObject;

 

        public Form1()

        {

            InitializeComponent();           

 

            // 初始化CustomizedObject對象

            myObject = new CustomizedObject { Date = DateTime.Now };

 

            // 綁定對象的屬性到label1

            label1.DataBindings.Add("Text", myObject, "Date");

 

            // 添加 DateChanged 事件的處理邏輯

            this.DateChanged += new DateChangedHandler(Form1_DateChanged);

       }

 

        private void Form1_DateChanged(object sender, DateChangedEventArgs e)

        {

            string message = string.Format(

                "DateChanged event triggered!nOldValue: {0}nNew Value: {1}",

                e.OldValue,

                e.NewValue);

            MessageBox.Show(message);

        }

 

        private void button1_Click(object sender, EventArgs e)

        {

            // 點擊按鈕改變對象的屬性值並觸發 DateChanged 事件

            DateChangedEventArgs ev = new DateChangedEventArgs

            {

                OldValue = myObject.Date,

                NewValue = myObject.Date.AddDays(1)

            };

            myObject.Date = ev.NewValue;

            DateChangedMethod(ev);

        }

 

 

        #region IDateChanged Members

 

        public event DateChangedHandler DateChanged;

 

        // 添加一個觸發 DateChanged 事件的通用方法

        protected virtual void DateChangedMethod(DateChangedEventArgs e)

        {

            if (DateChanged != null)

            {

                DateChanged(this, e);

            }

        }

 

        #endregion

    }

 

    // 自定義對象 CustomizedObject 並實現 INotifyPropertyChanged 和 IDateChanged 接口

    public class CustomizedObject : INotifyPropertyChanged

    {

        private DateTime dateValue;

 

        // 自定義一個 Date 屬性

        public DateTime Date

        {

            get { return dateValue; }

            set

            {

                dateValue = value;

                NotifyPropertyChanged("Date");

            }

        }

 

        #region INotifyPropertyChanged Members

 

        public event PropertyChangedEventHandler PropertyChanged;

 

        // 添加一個觸發 PropertyChanged 事件的通用方法

        protected virtual void NotifyPropertyChanged(string propertyName)

        {

            if (PropertyChanged != null)

            {

                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));

            }

        }

 

        #endregion

    }

 

    // DateChanged 事件委托

    public delegate void DateChangedHandler(object sender, DateChangedEventArgs e);

 

    // 用於封裝事件的接口

    public interface IDateChanged

    {

        event DateChangedHandler DateChanged;

    }

 

    // DateChanged 事件參數

    public class DateChangedEventArgs : EventArgs

    {

        public DateTime OldValue { get; set; }

        public DateTime NewValue { get; set; }

    }

}

 

擴展:https://www.codeprj.com/blog/50888a1.html


免責聲明!

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



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