Come impostare un'associazione nel codice?


96

Ho la necessità di impostare un'associazione nel codice.

Non riesco a farlo bene anche se.

Questo è quello che ho provato:

XAML:

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

Codice dietro:

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

La proprietà non si aggiorna quando l'ho impostata.

Che cosa sto facendo di sbagliato?

Risposte:


193

Sostituire:

myBinding.Source = ViewModel.SomeString;

con:

myBinding.Source = ViewModel;

Esempio:

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

La tua fonte dovrebbe essere giusta ViewModel, la .SomeStringparte viene valutata da Path( Pathpuò essere impostata dal costruttore o dalla Pathproprietà).


14
Puoi anche usare txtText.SetBinding (TextBox.TextProperty, myBinding) al posto dell'ultima riga solo per ridurre la digitazione :)
Manish Dubey

5
@ManishDubey Il vantaggio del metodo statico è che il primo parametro è definito come DependencyObject, quindi abilita il data binding su oggetti che non derivano da FrameworkElement o FrameworkContentElement (come Freezables).
FreddyFlares

Grazie per questo. Ha lottato un po 'alla ricerca di un esempio come questo
Jesse Roper

11

È necessario modificare l'origine in oggetto viewmodel:

myBinding.Source = viewModelObject;

1

Oltre alla risposta di Dyppl , penso che sarebbe bello inserire questa all'interno OnDataContextChangeddell'evento:

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

Abbiamo anche avuto casi in cui abbiamo appena salvato il DataContextin una proprietà locale e lo abbiamo utilizzato per accedere alle proprietà viewmodel. La scelta ovviamente è tua, mi piace questo approccio perché è più coerente con il resto. Puoi anche aggiungere alcune convalide, come i controlli nulli. Se davvero cambi il tuo DataContextgiro, penso che sarebbe bello chiamare anche:

BindingOperations.ClearBinding(myText, TextBlock.TextProperty);

per cancellare l'associazione del vecchio viewmodel ( e.oldValuenel gestore eventi).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.