Как установить привязку в коде?

98

Мне нужно установить привязку в коде.

Я не могу понять это правильно.

Вот что я пробовал:

XAML:

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

Код позади:

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

Свойство не обновляется, когда я его устанавливаю.

Что я делаю не так?

Виллем
источник

Ответы:

195

Заменить:

myBinding.Source = ViewModel.SomeString;

с участием:

myBinding.Source = ViewModel;

Пример:

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

Ваш источник должен быть справедливым ViewModel, .SomeStringчасть оценивается из Path( Pathможет быть установлен конструктором или Pathсвойством).

Dyppl
источник
14
Вы также можете использовать txtText.SetBinding (TextBox.TextProperty, myBinding) вместо последней строки, просто чтобы уменьшить ввод текста :)
Маниш Дубей,
6
@ManishDubey Преимущество статического метода заключается в том, что первый параметр определен как DependencyObject, поэтому он обеспечивает привязку данных к объектам, которые не являются производными от FrameworkElement или FrameworkContentElement (например, Freezables).
FreddyFlares 09
Спасибо за это. Немного потрудился найти такой пример
Джесси Ропер
12

Вам нужно изменить источник на объект viewmodel:

myBinding.Source = viewModelObject;
Bartosz.lipinski
источник
2

В дополнение к ответу на Dyppl , я думаю , что было бы неплохо , чтобы поместить это внутри OnDataContextChangedсобытия:

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

У нас также были случаи, когда мы просто сохраняли в DataContextлокальном свойстве и использовали его для доступа к свойствам модели просмотра. Выбор, конечно, за вами, мне нравится этот подход, потому что он больше соответствует остальным. Вы также можете добавить некоторую проверку, например нулевые проверки. Если вы действительно измените свое DataContextмнение, я думаю, было бы неплохо также позвонить:

BindingOperations.ClearBinding(myText, TextBlock.TextProperty);

чтобы очистить привязку старой модели просмотра ( e.oldValueв обработчике событий).

соммен
источник