Wie setze ich eine Bindung im Code?

96

Ich muss eine Bindung im Code festlegen.

Ich kann es nicht richtig machen.

Das habe ich versucht:

XAML:

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

Code dahinter:

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");
      }
    }

Die Eigenschaft wird nicht aktualisiert, wenn ich sie einstelle.

Was mache ich falsch?

Willem
quelle

Antworten:

193

Ersetzen:

myBinding.Source = ViewModel.SomeString;

mit:

myBinding.Source = ViewModel;

Beispiel:

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);

Ihre Quelle sollte gerecht sein ViewModel, das .SomeStringTeil wird aus dem ausgewertet Path(das Pathkann vom Konstruktor oder von der PathEigenschaft festgelegt werden).

Dyppl
quelle
14
Sie können auch txtText.SetBinding (TextBox.TextProperty, myBinding) anstelle der letzten Zeile verwenden, um die Eingabe zu reduzieren :)
Manish Dubey
5
@ManishDubey Der Vorteil der statischen Methode besteht darin, dass der erste Parameter als DependencyObject definiert ist und somit die Datenbindung für Objekte ermöglicht, die nicht von FrameworkElement oder FrameworkContentElement abgeleitet sind (z. B. Freezables).
FreddyFlares
Danke dafür. Kämpfte ein bisschen und suchte nach einem Beispiel wie diesem
Jesse Roper
11

Sie müssen die Quelle in das Ansichtsmodellobjekt ändern:

myBinding.Source = viewModelObject;
Baalazamon
quelle
1

Neben der Antwort von Dyppl halte ich es für schön, dies in die OnDataContextChangedVeranstaltung aufzunehmen:

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);
}

Wir hatten auch Fälle, in denen wir das nur DataContextin einer lokalen Eigenschaft gespeichert und damit auf die Eigenschaften des Ansichtsmodells zugegriffen haben. Die Wahl liegt natürlich bei Ihnen. Ich mag diesen Ansatz, weil er besser mit dem Rest übereinstimmt. Sie können auch eine Validierung hinzufügen, z. B. Nullprüfungen. Wenn Sie sich tatsächlich ändern DataContext, wäre es schön, auch anzurufen:

BindingOperations.ClearBinding(myText, TextBlock.TextProperty);

um die Bindung des alten Ansichtsmodells zu löschen ( e.oldValueim Ereignishandler).

Sommmen
quelle