5

ちょっとした質問:
wpf では、codebehind でテキスト ボックスの updatesourcetrigger を設定および取得するにはどうすればよいですか?
ありがとう

更新:
AngleWPFのコードに従います:

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

        var myBinding
          = bndExp.ParentBinding;

        var updateSourceTrigger = myBinding.UpdateSourceTrigger;

しかし、私は例外を得ました:

タイプ 'System.Reflection.TargetInvocationException' の未処理の例外が PresentationFramework.dll で発生しました 追加情報: 呼び出しのターゲットによって例外がスローされました。

4

3 に答える 3

14

UpdateSourceTriggerの とはどういう意味TextBoxですか? のことを言いたいUpdateSourceTriggerのですか?TextBox.TextPropertyBinding

たとえば、TextBox名前付きのプロパティが何らかのソースにバインドされている場合、呼び出しを介してmyTextBoxそのプロパティとオブジェクトをText簡単に取得できます。UpdateSourceTriggerBindingGetBindingExpression()

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

   var myBinding
     = bndExp.ParentBinding; 

   var updateSourceTrigger
     = myBinding.UpdateSourceTrigger;

しかし、すでに使用されているバインディングを設定 するのは難しいです。UpdateSourceTriggerたとえば、上記の場合、 を別のものに設定することはできmyBinding.UpdateSourceTriggerません。バインディング オブジェクトが既に使用されている場合、これは許可されません。

バインディング オブジェクトのディープ クローンを作成し、それに newUpdateSourceTriggerを設定して、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

これを実装するもう 1 つの方法は、TextBox で読み込まれたイベント ハンドラーでバインディングを設定することです。以下は TextBox の xaml です。

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

TxtName_OnLoaded eventhandler のコード ビハインドでは、新しい 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 のオブジェクトを作成しました。また、新しく作成された Binding オブジェクトに UpdateSourceTrigger を割り当てます。

バインディングには、複数の検証規則を含めることができます。そこに検証ルールを追加します。これで、バインディングをテキストボックスの TextProperty に設定できます。

利点: xaml では不可能なコード ビハインドから、複数の依存関係オブジェクトを Validation Rule オブジェクトのプロパティにバインドできます。例えば:

これを使用して、TextChanged イベントで入力を検証し、入力を、ApplicationViewModel で Grid にバインドされた public ObservableCollection プロパティとして保存されているアイテムのリストと比較します。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 を返します。この実装を通じて、実行時に入力の一意性をチェックします。

皆さんが楽しんでくれたことを願っています。

于 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 に答える