C#利用Lambda和Expression實現資料的動態繫結
阿新 • • 發佈:2019-02-15
在程式開發過程中,有時為了讓資料能夠實時更新,我們會採用資料繫結來實現。
一般我們資料繫結時我們是這樣寫的
public class Helper : INotifyPropertyChanged { #region statusInfo Property private string statusInfo_ = ""; public string statusInfo_pro { get { return statusInfo_; } set { if (value == statusInfo_) { return; } statusInfo_ = value; NotifyPropertyChanged(() => statusInfo_pro); } } #endregion #region statusInfo NotifyPropertyChanged public void NotifyPropertyChanged<T>(Expression<Func<T>> property) { if (PropertyChanged == null) { return; } var memberExpression = property.Body as MemberExpression; if (memberExpression == null) { return; } PropertyChanged.Invoke(this, new PropertyChangedEventArgs(memberExpression.Member.Name)); } public event PropertyChangedEventHandler PropertyChanged; #endregion } private Helper helper_=new Helper(); private void binding() { textbox1.DataBindings.Add("Text",helper,"statusInfo_pro"); }
其中Helper是繼承介面INotifyPropertyChanged,因為資料繫結的實現主要依賴於INotifyPropertyChanged介面。
如果要實現雙向資料繫結(即資料來源Helper.statusInfo_pro改變了會影響繫結的控制元件,繫結的控制元件資料改變了會自動更新到資料來源Helper.statusInfo_pro上),這時需要修改binding的實現,具體如下:
private void binding() { textbox1.DataBindings.Add("Text",helper,"statusInfo_pro",false,DataSourceUpdateMode.OnPropertyChanged); }
但是,在開發時,每次在資料繫結時都要寫繫結控制元件和繫結資料來源對應欄位的名字,即"Text"和"statusInfo_pro",有時稍加不注意就會寫錯,這樣就會導致繫結資料出錯,或者繫結失敗。那有沒有什麼辦法可以改善呢?
如果能夠在資料繫結時這樣寫
private void binding()
{
textbox1.DataBindings.Add(textbox1.Text,helper,helper.statusInfo_pro,false,DataSourceUpdateMode.OnPropertyChanged);
}
那麼就不會出現寫錯的問題。因為Text是textbox1的屬性,statusInfo_pro是helper的屬性。
基於這種想法,最終採用Lambda和Expression實現。其實現程式碼如下:
private void binding()
{
textbox1.DataBindings.Add(fetchPropertyName(() =>textbox1.Text),
helper,
fetchPropertyName(() => helper.statusInfo_pro),
false,
DataSourceUpdateMode.OnPropertyChanged
);
}
#region fetchPropertyName Function
public static string fetchPropertyName<T>(Expression<Func<T>> property)
{
MemberExpression memberExpression = property.Body as MemberExpression;
if (memberExpression == null)
{
return null;
}
return memberExpression.Member.Name;
}
#endregion
其中fetchPropertyName中的引數Expression<Func<T>> property在呼叫時使用了lambda表示式來傳遞引數。
雖然沒有達到預想的直接寫textbox1.Text,但換用了fetchPropertyName(() =>textbox1.Text)來實現,也是達到了目的。