Как установить и получить updateourcetrigger из текстового поля в codebehind? - PullRequest
2 голосов
/ 03 ноября 2011

Просто короткий вопрос:
В 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 ]

9 голосов
/ 03 ноября 2011

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

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

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

   var myBinding
     = bndExp.ParentBinding; 

   var updateSourceTrigger
     = myBinding.UpdateSourceTrigger;

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

Вам может потребоваться глубокий клон объекта привязки, установить новый UpdateSourceTrigger и присвоить его обратно * 1028.*.Клонирование не существует для 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);

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

2 голосов
/ 12 сентября 2013

Еще один способ реализовать это - установка привязки в обработчике событий, загруженном в TextBox. Ниже приведено описание 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);
    }
  }

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

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

0 голосов
/ 28 декабря 2014

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

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