1

入力範囲を制限したい TextBox があります。
In this simple example Int32 from 0 to 300.
実際の範囲はより複雑であり、有効な値を受け取って表示する以外に UI を関与させたくありません。

333 を入力すると、300 が返され、300 が TextBox に表示されます。

ここに問題があります:
3001 の数字を追加すると、セットは 300 の値を割り当て
ます。get が呼び出され、300 が返さ
れます。

3001 を貼り付けると、正しく 300
が表示されます。失敗するのは、1 回のキー ストロークで 4 桁 (またはそれ以上) の数字を作成した場合のみです。

<TextBox Text="{Binding Path=LimitInt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="60" Height="20"/>

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    protected void NotifyPropertyChanged(String info)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }

    private Int32 limitInt = 0;

    public MainWindow()
    {
        InitializeComponent();
    }

    public Int32 LimitInt
    {
        get { return limitInt; }
        set
        {
            if (limitInt == value) return;
            limitInt = value;
            if (limitInt < 0) limitInt = 0;
            if (limitInt > 300) limitInt = 300; 
            NotifyPropertyChanged("LimitInt");
        }
    }
}
4

2 に答える 2

3

これは、バインディング操作の途中でバインディング ソースの値を変更しているためだと思います。バインディングで使用するUpdateSourceTrigger=PropertyChangedと、キーを押すたびに再評価するように指示されます。その場合、Bindingソースからプルしてターゲットを更新しようとするのではなく、値をソースにプッシュします。

NotifyPropertyChanged を発生させた後でも、バインド操作の途中であるため、Target が更新されないことを想像します。

これを解決するには、 を削除しUpdateSourceTriggerてデフォルト ( LostFocus) のままにします。ユーザーがタブを押した後に発生することに慣れている限り、これを行うことはうまくいきます。

<TextBox Text="{Binding Path=LimitInt}" Width="60" Height="20"/>

(Mode=TwoWay は TextBox のデフォルトであるため、これを削除することもできます)。

キーを押すたびに評価したい場合は、マスクされた編集を調べ、キープレス/キーダウンを処理して、入力TextBox後に値を変更しようとするのではなく、値が に入力されないようにすることをお勧めします。

于 2013-03-06T19:40:31.800 に答える
1

検証を使用することをお勧めします。

方法は次のとおりです。

チェックするXAMLを定義しますPreviewTextInput

<TextBox Text="{Binding Path=LimitInt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" PreviewTextInput="CheckNumberValidationHandler" Width="60" Height="20"/>

次に、検証ハンドラーを設定します。

/// <summary>
/// Check to make sure the input is valid
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CheckNumberValidationHandler(object sender, TextCompositionEventArgs e) {
    if(IsTextAllowed(e.Text)) {
    Int32 newVal;
    newVal = Int32.Parse(LimitInt.ToString() + e.Text);
    if(newVal < 0) {
        LimitInt = 0;
        e.Handled = true;
    }
    else if(newVal > 300) {
        LimitInt = 300;
        e.Handled = true;
    }
    else {
        e.Handled = false;
    }
    }
    else {
    e.Handled = true;
    }
}

/// <summary>
/// Check if Text is allowed
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
private static bool IsTextAllowed(string text) {
    Regex regex = new Regex("[^0-9]+");
    return !regex.IsMatch(text);
}

編集:チェックしたところ、.NET4.0で動作します:)

于 2013-03-06T21:08:03.233 に答える