如何在代码隐藏中设置和获取文本框的更新源触发器?

发布于 2024-12-13 07:32:19 字数 537 浏览 3 评论 0原文

只是一个简短的问题:
在 wpf 中,如何在代码隐藏中设置和获取文本框的 updatesourcetrigger ?
谢谢

更新:
我遵循 AngleWPF 的代码:

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

        var myBinding
          = bndExp.ParentBinding;

        var updateSourceTrigger = myBinding.UpdateSourceTrigger;

但我得到了例外:

未处理的类型异常 “System.Reflection.TargetInitationException”发生在 PresentationFramework.dll 附加信息:已出现异常 由调用目标抛出。

Just a short question :
In wpf, how do I set and get updatesourcetrigger of a textbox in codebehind ?
Thanks

Update :
I follow AngleWPF's code :

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

        var myBinding
          = bndExp.ParentBinding;

        var updateSourceTrigger = myBinding.UpdateSourceTrigger;

But I got the exception :

An unhandled exception of type
'System.Reflection.TargetInvocationException' occurred in
PresentationFramework.dll Additional information: Exception has been
thrown by the target of an invocation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

亣腦蒛氧 2024-12-20 07:32:19

TextBoxUpdateSourceTrigger 是什么意思?您的意思是说 TextBox.TextPropertyBindingUpdateSourceTrigger 吗?

例如,如果您有一个名为 myTextBoxTextBox,其 Text 属性绑定到某个源,那么您可以轻松地获取它通过 GetBindingExpression() 调用 UpdateSourceTriggerBinding 对象。

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

   var myBinding
     = bndExp.ParentBinding; 

   var updateSourceTrigger
     = myBinding.UpdateSourceTrigger;

但为已使用的绑定设置 UpdateSourceTrigger 是很棘手的。例如,在上述情况下,您将无法将 myBinding.UpdateSourceTrigger 设置为其他内容。当绑定对象已在使用中时,这是不允许的。

您可能必须深度克隆绑定对象并为其设置新的UpdateSourceTrigger,并将其分配回TextBoxBinding 类不存在克隆。您可能必须为此编写自己的克隆代码。

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

或者,您也可以尝试分离现有绑定并更新它,然后将其分配回来...

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

如果这些提示有帮助,请告诉我。

What do you mean by UpdateSourceTrigger of TextBox? You mean to say UpdateSourceTrigger of TextBox.TextProperty's Binding?

E.g. if you have a TextBox named myTextBox having its Text property bound to some source then you can easily get it's UpdateSourceTrigger and Binding object via GetBindingExpression() call.

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

   var myBinding
     = bndExp.ParentBinding; 

   var updateSourceTrigger
     = myBinding.UpdateSourceTrigger;

But it is tricky to set UpdateSourceTrigger for an already used binding. E.g. in the above case you wont be able to set the myBinding.UpdateSourceTrigger to something else. This is not allowed when a binding object is already in use.

You may have to deep clone the binding object and set new UpdateSourceTrigger to it and assign it back to the TextBox. Cloning does not exist for Binding class. You may have to write your own cloning code for the same.

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

Alternately ou can also try to detatch the existing Binding and update it and assign it back...

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

Let me know if any of these tips helps.

寒尘 2024-12-20 07:32:19

另一种实现方法是在 TextBox 加载的事件处理程序中设置绑定。
下面是 TextBox 的 xaml:

    <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 属性(与 Grid 绑定)的 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);
    }
  }

上面的代码接受输入并检查“Inputs”可观察集合中的可用性。如果值存在,规则给出 false ValidationResult。通过这个实现,我检查运行时输入的唯一性。

希望你们喜欢它。

A another way to implement it is setting binding in TextBox loaded eventhandler.
Below is the xaml of TextBox:

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

Now in code behind for TxtName_OnLoaded eventhandler will will create new Binding object and will initialize it as per our needs. Also we will add ValidationRule into it.

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

As you can see in above implementation we have created an object of Binding with new binding path. Also assigned UpdateSourceTrigger to newly created Binding object.

A binding can have multiple validation rules. We will add a validation rule into it. Now we can set the binding to the TextProperty of textbox.

Benefits: You can bind multiple dependency objects to the properties of Validation Rule object from code behind which is not possible with xaml. For example:

I used it to validate inputs on TextChanged event, where I compare input with the list of Items stored as public ObservableCollection property, bound with Grid, in ApplicationViewModel. Code of ValidationRule is as follows:

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

Above code takes input and checks availability in the "Inputs" observable collection. Rule give false ValidationResult if value exists. Through this implementation I check uniqueness of inputs on run-time.

Hope you guys have enjoyed it.

大姐,你呐 2024-12-20 07:32:19

我认为这是执行此操作的正确方法:

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

I think this the right way to do this:

 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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文