2

WPF TextBox コントロールのキーボード ウェッジ スキャンをサポートする一般的な方法を探しています。

(より高度なWPF機能に関しては、私は本当に初心者なので、研究に多くの時間を費やす前に、正しい方向に進んでいるかどうかを尋ねたいと思います。)

私がやりたいことは、添付プロパティ (または何か) を TextBoxes に追加して、ボックスへのすべての入力を読み取り、スキャンされた入力でカスタム "ScanCompleted" コマンドを呼び出すことです。

添付プロパティがこれに適していない場合、独自のカスタム「ScanableTextBox」を下回らずに TextBox でこのコマンドを取得する方法はありますか?

(注: (タイプされたデータではなく) スキャンの基準は、Pause キー (#19) で開始し、Return キー (#13) で終了することです。)

4

1 に答える 1

4

これはおそらく添付プロパティ (動作) で実現できると思いますが、 、、および同様のメソッドを単純にサブクラス化TextBoxしてオーバーライドし、カスタム機能を追加する方がはるかに単純で簡単です。OnTextChangedOnKeyDownOnKeyUp

この方法で独自のコントロールを作成してみませんか?

更新: アタッチされた動作

派生コントロールが本当に必要ない場合は、これを実現する添付の動作を次に示します (以下の説明)。

  public class ScanReading
  {
    private static readonly IDictionary<TextBox, ScanInfo> TrackedTextBoxes = new Dictionary<TextBox, ScanInfo>();

    public static readonly DependencyProperty ScanCompletedCommandProperty =
      DependencyProperty.RegisterAttached("ScanCompletedCommand", typeof (ICommand), typeof (ScanReading), 
      new PropertyMetadata(default(ICommand), OnScanCompletedCommandChanged));

    public static void SetScanCompletedCommand(TextBox textBox, ICommand value)
    {
      textBox.SetValue(ScanCompletedCommandProperty, value);
    }

    public static ICommand GetScanCompletedCommand(TextBox textBox)
    {
      return (ICommand) textBox.GetValue(ScanCompletedCommandProperty);
    }

    private static void OnScanCompletedCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
      var textBox = d as TextBox;
      if (textBox == null)
        return;

      var command = (ICommand) e.NewValue;

      if (command == null)
      {
        textBox.Unloaded -= OnTextBoxUnloaded;
        textBox.KeyUp -= OnTextBoxKeyUp;
        TrackedTextBoxes.Remove(textBox);
      }
      else
      {
        textBox.Unloaded += OnTextBoxUnloaded;
        TrackedTextBoxes.Add(textBox, new ScanInfo(command));

        textBox.KeyUp += OnTextBoxKeyUp;
      }
    }

    static void OnTextBoxKeyUp(object sender, KeyEventArgs e)
    {
      var textBox = (TextBox) sender;

      var scanInfo = TrackedTextBoxes[textBox];
      if (scanInfo.IsTracking)
      {
        if (e.Key == Key.Return)
        {
          scanInfo.ScanCompletedCommand.Execute(textBox.Text);
          scanInfo.IsTracking = false;
        }
      }
      else if (string.IsNullOrEmpty(textBox.Text) && e.Key == Key.Pause)
      {
        TrackedTextBoxes[textBox].IsTracking = true;
      }
    }

    static void OnTextBoxUnloaded(object sender, RoutedEventArgs e)
    {
      var textBox = (TextBox) sender;
      textBox.KeyUp -= OnTextBoxKeyUp;
      textBox.Unloaded -= OnTextBoxUnloaded;
      TrackedTextBoxes.Remove(textBox);
    }
  }

  public class ScanInfo
  {
    public ScanInfo(ICommand scanCompletedCommand)
    {
      ScanCompletedCommand = scanCompletedCommand;
    }

    public bool IsTracking { get; set; }
    public ICommand ScanCompletedCommand { get; private set; }
  }

これを次のTextBoxように宣言して使用します (localは添付プロパティの名前空間であり、ScanCompletedビューICommandモデルでは です)。

<TextBox local:ScanReading.ScanCompletedCommand="{Binding ScanCompleted}" />

このプロパティが設定されるTextBoxと、関連付けられた とともに静的コレクションにを追加しICommandます。

キーが押されるたびに、それがPauseキーであるかどうかを確認します。そうであり、が空の場合はTextBox、フラグを設定しtrueて、キーの検索を開始しEnterます。

キーが押されるたびに、それがEnterキーであるかどうかを確認します。そうであれば、コマンドを実行して値を渡し、TextBox.Textそのフラグを にリセットfalseTextBoxます。

TextBox.Unloadedまた、イベント サブスクリプションをクリーンアップTextBoxし、静的リストから削除するイベントのハンドラーも追加しました。

于 2012-04-30T20:51:28.030 に答える