How to set a binding in Code?

C#WpfXamlData Binding

C# Problem Overview


I have the need to set a binding in code.

I can't seem to get it right tho.

This is what i have tried:

XAML:

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

Code behind:

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

The property is not updating when i set it.

What am i doing wrong?

C# Solutions


Solution 1 - C#

Replace:

myBinding.Source = ViewModel.SomeString;

with:

myBinding.Source = ViewModel;

Example:

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

Your source should be just ViewModel, the .SomeString part is evaluated from the Path (the Path can be set by the constructor or by the Path property).

Solution 2 - C#

You need to change source to viewmodel object:

myBinding.Source = viewModelObject;

Solution 3 - C#

In addition to the answer of Dyppl, I think it would be nice to place this inside the OnDataContextChanged event:

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

We have also had cases were we just saved the DataContext to a local property and used that to access viewmodel properties. The choice is of course yours, I like this approach because it is more consistent with the rest. You can also add some validation, like null checks. If you actually change your DataContext around, I think it would be nice to also call:

BindingOperations.ClearBinding(myText, TextBlock.TextProperty);

to clear the binding of the old viewmodel (e.oldValue in the event handler).

Solution 4 - C#

Example:

DataContext:

  class ViewModel
  {
    public string SomeString
    {
      get => someString;
      set 
      {
        someString = value;
        OnPropertyChanged(nameof(SomeString));
      }
    }
  }

Create Binding:

  new Binding("SomeString")
  {
    Mode = BindingMode.TwoWay,
    UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
  };

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWillemView Question on Stackoverflow
Solution 1 - C#DypplView Answer on Stackoverflow
Solution 2 - C#bartosz.lipinskiView Answer on Stackoverflow
Solution 3 - C#sommmenView Answer on Stackoverflow
Solution 4 - C#Stepan IvanenkoView Answer on Stackoverflow