2017-05-01 41 views
2

讓我們假設您有一個具有屬性的對象,您將控件綁定到該對象。就像這樣:綁定到引用,而不是對象

MyClass MyObject = new MyClass(); 
MyObject.MyProperty = "Hello StackOverflow!"; 
MyTextBox.DataBindings.Add("Text", MyObject, nameOf(MyObject.MyProperty); 

然後你改變MyObjectMyClass一個新的實例,就像這樣:

MyObject = new MyClass(); 
MyObject.MyProperty = "I've made a new instance of my class..."; 

然後MyTextBox仍將被綁定到MyProperty設置爲的的MyClass實例「你好,StackOverflow!「。無論如何設置數據綁定,以便它堅持類的新實例?我知道我可以簡單地再次設置DataBindings,但有時這並不像這個例子那麼簡單。

+1

不是。您正在綁定一個對象而不是變量名稱。 –

+1

是的,綁定到你的viewmodel的屬性。使您的視圖模型成爲綁定的源代碼,併爲其指定屬性的路徑。確保你的viewmodel正確地推動INotifyPropertyChanged。 –

回答

0

數據綁定支持源屬性的屬性路徑。因此,只要您將MyObject變量放在另一個可用於數據綁定的對象中並將其作爲屬性公開,則可以指定引用保留該值的屬性的屬性名稱,然後指定一個點,然後指定您想要的屬性。

例如,假設你有一個Model類與MyClass屬性值:(以上數據假設一個輔助方法_UpdateField(),處理更新的領域,並根據需要提高PropertyChanged事件)

class Model : INotifyPropertyChanged 
{ 
    private MyClass _myClass; 
    public MyClass MyClass 
    { 
     get { return _myClass; } 
     set { _UpdateField(ref _myClass, value); } 
    } 
} 

然後,你可以定義你像這樣綁定:

Model model = new Model(); // initialized somewhere you can access this reference later 
model.MyClass.MyProperty = "Hello StackOverflow!"; 
MyTextBox.DataBindings.Add("Text", model, 
    nameof(Model.MyClass) + "." + nameof(MyClass.MyProperty); 

然後,當你要更新MyClass對象,請更改model.MyClass屬性值。綁定將相應地更新目標值。


這裏有一個完整的示例(除*了.Designer.cs文件…只要確保有窗體上的LabelButton,與各自的默認名稱和認購Button.Click事件在下面的代碼處理程序):

public partial class Form1 : Form 
{ 
    private readonly C2[] _rgc2 = 
    { 
     new C2 { Text = "First C2" }, 
     new C2 { Text = "Second C2" }, 
    }; 

    private readonly C1 _c1 = new C1(); 

    private bool _toggle = false; 

    public Form1() 
    { 
     InitializeComponent(); 
     label1.DataBindings.Add("Text", _c1, nameof(C1.C2) + "." + nameof(C2.Text)); 
     _UpdateC2(); 
    } 

    private void _UpdateC2() 
    { 
     _c1.C2 = _rgc2[_toggle ? 1 : 0]; 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     _toggle = !_toggle; 
     _UpdateC2(); 
    } 
} 

class C1 : NotifyPropertyChangedBase 
{ 
    private C2 _c2; 

    public C2 C2 
    { 
     get { return _c2; } 
     set { _UpdateField(ref _c2, value); } 
    } 
} 

class C2 : NotifyPropertyChangedBase 
{ 
    private string _text; 

    public string Text 
    { 
     get { return _text; } 
     set { _UpdateField(ref _text, value); } 
    } 
} 

class NotifyPropertyChangedBase : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void _UpdateField<T>(ref T field, T newValue, 
     Action<T> onChangedCallback = null, 
     [CallerMemberName] string propertyName = null) 
    { 
     if (EqualityComparer<T>.Default.Equals(field, newValue)) 
     { 
      return; 
     } 

     T oldValue = field; 

     field = newValue; 
     onChangedCallback?.Invoke(oldValue); 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
相關問題