データバインドされたWPFテキストボックスがあります。テキストボックスへのユーザー入力を制限して、数値と単一のピリオド(小数を表示するため)のみを受け入れるようにする必要があります。
これを「Winforms」の方法で処理し、KeyPressイベントの各入力を検証できることはわかっていますが、WPFでこれを行うためのよりクリーンで適切な方法があるかどうか疑問に思いました(特にテキストボックスをデータバインディングしているため)。
WPFが提供するValidationRulesを使用します。
xamlは次のようになります。
<TextBox>
<TextBox.Text>
<Binding Path="Name">
<Binding.ValidationRules>
<ExceptionValidationRule />
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
textboxプロパティのコードは次のようになります(検証に正規表現を使用):
public string Name
{
get { return _name; }
set
{
_name = value;
if (!Regex.IsMatch(value, @"^((?:[1-9]\d*)|(?:(?=[\d.]+)(?:[1-9]\d*|0)\.\d+))$"))
{
throw new ApplicationException("Please enter only numbers/decimals.");
}
}
}
出典:WPFでの検証
上記の正規表現:このRubularリンク^((?:[1-9]\d*)|(?:(?=[\d.]+)(?:[1-9]\d*|0)\.\d+))$
でテストできます
正規表現はこれらと一致します:
1.2
22522
0.33
3.90000
しかし、これらではありません:(それらのいくつかを許可するために正規表現を微調整することができます)
.999
23.35.1343
03423.23423
データバインディングは、データバインディング先のオブジェクトとの間でやり取りされる値に影響します。ユーザーがキーを押さないようにするには、マスクされたテキストボックス(winformsでは、WPFについては不明)を使用するか、テキストボックスでKeyPressedEventを処理して、押されたくないキーが発生しないようにする必要があります。
以下のコードを使用して、数字と小数点以下1桁のみを許可しました
private void textBoxPrice_KeyPress( object sender, KeyPressEventArgs e )
{
if( !char.IsControl( e.KeyChar )
&& !char.IsDigit( e.KeyChar )
&& e.KeyChar != '.' )
{
e.Handled = true;
}
// only allow one decimal point
if( e.KeyChar == '.'
&& ( sender as TextBox ).Text.IndexOf( '.' ) > -1 )
{
e.Handled = true;
}
}
キープレスイベントを使用し、ASCII文字でキープレスイベントを検証するだけです。
e.KeyCode> 47 && e.KeyCode <58は、ユーザーが数字以外の文字を押さないように制限します。
正確なコードサンプルが必要な場合は、しばらく待ちます:)