112 votes

Comment définir une liaison dans le code ?

J'ai besoin de définir une liaison dans le code.

Je n'arrive pas à le faire correctement.

C'est ce que j'ai essayé :

XAML :

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

Code derrière :

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 propriété n'est pas mise à jour lorsque je la définis.

Qu'est-ce que je fais mal ?

216voto

Dyppl Points 4731

Remplacer :

myBinding.Source = ViewModel.SomeString;

avec :

myBinding.Source = ViewModel;

Exemple :

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

Votre source devrait être juste ViewModel le .SomeString est évaluée à partir de la partie Path (le Path peut être définie par le constructeur ou par la fonction Path propriété).

12voto

baalazamon Points 1728

Vous devez changer la source en objet viewmodel :

myBinding.Source = viewModelObject;

2voto

sommmen Points 22

En plus de la réponse de Dyppl je pense qu'il serait bon de le placer à l'intérieur de l'interface de l'entreprise. OnDataContextChanged événement :

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

Nous avons également eu des cas où nous avons juste sauvé la DataContext à une propriété locale et l'utilise pour accéder aux propriétés du modèle de vue. Le choix vous appartient bien sûr, j'aime cette approche car elle est plus cohérente avec le reste. Vous pouvez également ajouter des validations, comme des vérifications de nullité. Si vous modifiez réellement votre DataContext autour, je pense que ce serait bien d'appeler aussi :

BindingOperations.ClearBinding(myText, TextBlock.TextProperty);

pour effacer la liaison de l'ancien modèle de vue ( e.oldValue dans le gestionnaire d'événements).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X