Как установить и получить updateourcetrigger из текстового поля в codebehind?

Просто короткий вопрос:
В wpf, как мне установить и получить updatesourcetrigger текстового поля в codebehind?
Спасибо

Обновить:
Я следую за кодом AngleWPF:

        var bndExp = BindingOperations.GetBindingExpression(this, TextBox.TextProperty);

        var myBinding
          = bndExp.ParentBinding;

        var updateSourceTrigger = myBinding.UpdateSourceTrigger;

Но я получил исключение:

Произошло необработанное исключение типа "System.Reflection.TargetInvocationException" в PresentationFramework.dll Дополнительная информация: Исключение было сгенерировано целью вызова.

3 ответа

Решение

Что вы подразумеваете под UpdateSourceTrigger из TextBox? Вы хотите сказать UpdateSourceTrigger из TextBox.TextProperty"s Binding?

Например, если у вас есть TextBox названный myTextBox имея его Text свойство связано с каким-то источником, то вы можете легко получить это UpdateSourceTrigger а также Binding объект через GetBindingExpression() вызов.

   var bndExp
     = BindingOperations.GetBindingExpression(myTextBox, TextBox.Textproperty);

   var myBinding
     = bndExp.ParentBinding; 

   var updateSourceTrigger
     = myBinding.UpdateSourceTrigger;

Но это сложно установить UpdateSourceTrigger для уже использованной привязки. Например, в приведенном выше случае вы не сможете установить myBinding.UpdateSourceTrigger к чему-то еще. Это не допускается, когда объект привязки уже используется.

Возможно, вам придется глубоко клонировать объект привязки и установить новый UpdateSourceTrigger к нему и назначить его обратно TextBox, Клонирование не существует для Binding учебный класс. Возможно, вам придется написать свой собственный код клонирования для того же.

  var newBinding = Clone(myBinding); //// <--- You may have to code this function.
  newBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
  myTextBox.SetBinding(TextBox.TextProperty, newBinding);

Кроме того, вы также можете попытаться отсоединить существующий Binding, обновить его и назначить обратно...

  myTextBox.SetBinding(TextBox.TextProperty, null);
  myBinding.UpdateSourceTrigger = UpdateSourceTrigger.Explicit;
  myTextBox.SetBinding(TextBox.TextProperty, myBinding);

Дайте мне знать, если какой-либо из этих советов поможет.

Еще один способ реализовать это - установка привязки в обработчике событий, загруженном в TextBox. Ниже приведен xaml TextBox:

    <TextBox Grid.Row="0" 
             x:Name="txtName"
             Text="{Binding Name}"
             Loaded="TxtName_OnLoaded" />

Теперь в коде для TxtName_OnLoaded обработчик событий создаст новый объект Binding и инициализирует его в соответствии с нашими потребностями. Также мы добавим ValidationRule в него.

    private void TxtName_OnLoaded(object sender, RoutedEventArgs e)
    {
      ApplicationViewModel appVm = this.DataContext as ApplicationViewModel;
      TextBox TxtName = sender as TextBox;

      if (TxtName == null)
        return;

      Binding newBinding = new Binding("Name");
      newBinding.ValidatesOnDataErrors = true;
      newBinding.ValidatesOnExceptions = true;
      newBinding.NotifyOnValidationError = true;
      newBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
      validator.ErrorMessage = "Labware name should be unique.";
      validator.ApplicationViewModel = appVm;
      if (!newBinding.ValidationRules.Contains(validator))
        newBinding.ValidationRules.Add(validator);
      TxtName.SetBinding(TextBox.TextProperty, newBinding);
    }

Как вы можете видеть в приведенной выше реализации, мы создали объект Binding с новым путем привязки. Также назначен UpdateSourceTrigger для вновь созданного объекта Binding.

Привязка может иметь несколько правил проверки. Мы добавим в него правило проверки. Теперь мы можем установить привязку к TextProperty текстового поля.

Преимущества: Вы можете привязать несколько объектов зависимостей к свойствам объекта правила валидации из кода, который недоступен в xaml. Например:

Я использовал его для проверки входных данных в событии TextChanged, где я сравниваю входные данные со списком элементов, хранящихся в виде открытого свойства ObservableCollection, связанного с сеткой, в ApplicationViewModel. Код ValidationRule выглядит следующим образом:

    public class UniqueValueValidator : ValidationRule
  {
    public string ErrorMessage { get; set; }
    public ApplicationViewModel ApplicationViewModel { get; set; }

    public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
    {
      if (value == null)
        return null;

      var lws = ApplicationViewModel.Inputs.Where(s => s.Name.Equals(value.ToString())).FirstOrDefault();
      if (lws != null)
        return new ValidationResult(false, ErrorMessage);


      return new ValidationResult(true, null);
    }
  }

Выше код принимает входные данные и проверяет доступность в наблюдаемой коллекции "Входы". Правило дает ложь ValidationResult, если значение существует. Благодаря этой реализации я проверяю уникальность входных данных во время выполнения.

Надеюсь, вам, ребята, понравилось.

Я думаю, что это правильный способ сделать это:

 Binding binding = new Binding();

 binding.Source = new CustomerViewModel();;
 binding.Path = new PropertyPath("Customer.Name");
 binding.Mode = BindingMode.TwoWay;
 binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
 txtCustName.SetBinding(TextBox.TextProperty, binding);
Другие вопросы по тегам