5

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

更新:
我遵循 AngleWPF 的代码:

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

        var myBinding
          = bndExp.ParentBinding;

        var updateSourceTrigger = myBinding.UpdateSourceTrigger;

但我得到了例外:

PresentationFramework.dll 中发生了“System.Reflection.TargetInvocationException”类型的未处理异常附加信息:调用目标引发了异常。

4

3 回答 3

14

你是什​​么UpdateSourceTrigger意思TextBox?你是说'sUpdateSourceTrigger的?TextBox.TextPropertyBinding

例如,如果您有一个TextBox名称myTextBox,其属性绑定到某个源,那么您可以通过调用Text轻松获取UpdateSourceTriggerBinding对象。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);

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

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

让我知道这些提示是否有帮助。

于 2011-11-03T05:00:13.810 回答
2

另一种实现它的方法是在 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 事件的输入,在此我将输入与 ApplicationViewModel 中存储为公共 ObservableCollection 属性、与 Grid 绑定的项目列表进行比较。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。通过这个实现,我检查了运行时输入的唯一性。

希望你们喜欢它。

于 2013-09-12T17:39:09.443 回答
0

我认为这是正确的方法:

 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);
于 2014-12-28T10:54:52.053 回答