Bagaimana cara mengatur pengikatan dalam Kode?

97

Saya memiliki kebutuhan untuk mengatur pengikatan kode.

Sepertinya aku tidak bisa melakukannya dengan benar.

Inilah yang saya coba:

XAML:

<TextBox Name="txtText"></TextBox>

Kode di belakang:

Binding myBinding = new Binding("SomeString");
myBinding.Source = ViewModel.SomeString;
myBinding.Mode = BindingMode.TwoWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(txtText, TextBox.TextProperty, myBinding);

ViewModel:

public string SomeString
    {
      get
      { 
          return someString;
      }
      set 
      { 
          someString= value;
          OnPropertyChanged("SomeString");
      }
    }

Properti tidak diperbarui saat saya menyetelnya.

Apa yang saya lakukan salah?

Willem
sumber

Jawaban:

194

Menggantikan:

myBinding.Source = ViewModel.SomeString;

dengan:

myBinding.Source = ViewModel;

Contoh:

Binding myBinding = new Binding();
myBinding.Source = ViewModel;
myBinding.Path = new PropertyPath("SomeString");
myBinding.Mode = BindingMode.TwoWay;
myBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
BindingOperations.SetBinding(txtText, TextBox.TextProperty, myBinding);

Sumber Anda harus adil ViewModel, .SomeStringbagian dievaluasi dari Path( Pathdapat disetel oleh konstruktor atau oleh Pathproperti).

Dyppl
sumber
14
Anda juga dapat menggunakan txtText.SetBinding (TextBox.TextProperty, myBinding) sebagai pengganti baris terakhir hanya untuk mengurangi pengetikan :)
Manish Dubey
5
@ManishDubey Manfaat metode statis adalah bahwa parameter pertama didefinisikan sebagai DependencyObject, sehingga memungkinkan pengikatan data pada objek yang tidak berasal dari FrameworkElement atau FrameworkContentElement (seperti Freezables).
FreddyFlares
Terima kasih untuk ini. Berjuang sedikit mencari contoh seperti ini
Jesse Roper
12

Anda perlu mengubah sumber ke objek viewmodel:

myBinding.Source = viewModelObject;
bartosz.lipinski
sumber
2

Selain jawaban dari Dyppl , saya pikir itu akan menyenangkan untuk menempatkan ini dalam OnDataContextChangedacara:

private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    // Unforunately we cannot bind from the viewmodel to the code behind so easily, the dependency property is not available in XAML. (for some reason).
    // To work around this, we create the binding once we get the viewmodel through the datacontext.
    var newViewModel = e.NewValue as MyViewModel;

    var executablePathBinding = new Binding
    {
        Source = newViewModel,
        Path = new PropertyPath(nameof(newViewModel.ExecutablePath))
    };

    BindingOperations.SetBinding(LayoutRoot, ExecutablePathProperty, executablePathBinding);
}

Kami juga memiliki kasus di mana kami baru saja menyimpan DataContextke properti lokal dan menggunakannya untuk mengakses properti model tampilan. Pilihan ada di tangan Anda, saya suka pendekatan ini karena lebih konsisten dengan yang lain. Anda juga dapat menambahkan beberapa validasi, seperti pemeriksaan null. Jika Anda benar-benar mengubah DataContextkeadaan, saya pikir akan menyenangkan juga untuk menelepon:

BindingOperations.ClearBinding(myText, TextBlock.TextProperty);

untuk menghapus pengikatan viewmodel lama ( e.oldValuedi event handler).

sommmen
sumber