2017-05-01 10 views
2

コントロールをバインドするオブジェクトをオブジェクトとしたいとしましょう。このように:オブジェクトではなく参照へのバインド

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

そして、あなたは、このように、MyClassの新しいインスタンスへMyObjectを変更します。

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

その後MyTextBoxまだMyPropertyに設定されているMyClassのインスタンスにバインドされます "こんにちはStackOverflow! "。とにかく、データバインディングを設定して、クラスの新しいインスタンスに固執するようにしますか?私は単にDataBindingsを再度設定できることを知っていますが、時にはこれはこの例のように単純ではありません。

+1

いいえ変数名ではなくオブジェクトをバインドしています。 –

+1

はい、あなたのビューモデルのプロパティにバインドします。あなたのビューモデルをバインディングのソースにして、プロパティへのパスを与えます。あなたのビューモデルがINotifyPropertyChangedを正しくインパクトしていることを確認してください。 –

答えて

0

データバインディングは、ソースプロパティのプロパティパスをサポートします。したがって、データバインディングに使用できる別のオブジェクトに変数MyObjectを配置し、それをプロパティとして公開する限り、その値を保持するプロパティを参照するプロパティ名を指定してから、実際に必要なプロパティを指定することができます。例えば

、あなたがMyClassプロパティ値を持つModelクラスを持っていると仮定してみましょう:

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

(上記は、フィールドを更新し、必要に応じてPropertyChangedイベントを上げる処理するヘルパーメソッド_UpdateField()を前提としています。)

次にあなたがそうのようなバインディング定義することができます:あなた、そして、

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ファイル&hellipを除き、ちょうど彼らのデフォルト名で、フォーム上の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)); 
    } 
} 
関連する問題