如标题所述。 我看过从TextBox继承的方法,但唯一明智的重载是"OnKeyDown",但它只给了我一个来自Key枚举的键(没有使用Char.IsNumeric()的方法)。
如标题所述。 我看过从TextBox继承的方法,但唯一明智的重载是"OnKeyDown",但它只给了我一个来自Key枚举的键(没有使用Char.IsNumeric()的方法)。
我采纳了Nidhal的建议答案,并稍作修改以处理数字上方字符的移位情况(即!@#$ %^&*()),因为该解决方案仍将允许这些字符出现在文本框中。
private void NumClient_KeyDown(object sender, KeyEventArgs e)
{
// Handle Shift case
if (Keyboard.Modifiers == ModifierKeys.Shift)
{
e.Handled = true;
}
// Handle all other cases
if (!e.Handled && (e.Key < Key.D0 || e.Key > Key.D9))
{
if (e.Key < Key.NumPad0 || e.Key > Key.NumPad9)
{
if (e.Key != Key.Back)
{
e.Handled = true;
}
}
}
}
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interactivity;
namespace DataArtist
{
public class NumericOnly : Behavior<TextBox>
{
private string Text { get; set; }
private bool shiftKey;
public bool StripOnExit { get; set; }
public NumericOnly()
{
StripOnExit = false;
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.KeyDown += KeyDown;
AssociatedObject.KeyUp += KeyUp;
AssociatedObject.GotFocus += GotFocus;
AssociatedObject.LostFocus += LostFocus;
}
void KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Shift)
{
shiftKey = false;
}
}
void KeyDown(object sender, KeyEventArgs e)
{
if (StripOnExit != false || e.Key == Key.Tab || e.Key == Key.Enter)
{
return;
}
if (e.Key == Key.Shift)
{
shiftKey = true;
}
else
{
if (IsNumericKey(e.Key) == false)
{
e.Handled = true;
}
}
}
void GotFocus(object sender, RoutedEventArgs e)
{
Text = AssociatedObject.Text;
}
private void LostFocus(object sender, RoutedEventArgs e)
{
if (AssociatedObject.Text == Text)
{
return;
}
string content = string.Empty;
foreach (var c in AssociatedObject.Text)
{
if (Char.IsNumber(c) == true)
{
content += c;
}
}
AssociatedObject.Text = content;
}
public bool IsNumericKey(Key key)
{
if (shiftKey == true)
{
return false;
}
string code = key.ToString().Replace("NumPad", "D");
if (code[0] == 'D' && code.Length > 1)
{
return (Char.IsNumber(code[1]));
}
return false;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.KeyDown -= KeyDown;
AssociatedObject.LostFocus -= LostFocus;
AssociatedObject.GotFocus -= GotFocus;
}
}
}
private void Numclient_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key < Key.D0 || e.Key > Key.D9)
{
if (e.Key < Key.NumPad0 || e.Key > Key.NumPad9)
{
if (e.Key != Key.Back && e.Key != Key.Shift)
{
e.Handled = true;
}
}
}
}
请查看工具包中的NumericUpDown控件http://codeplex.com/Silverlight,也许您可以使用该控件,或查看源代码来实现自己的数字文本框。
看看这个,它使用了附加属性覆盖文本框。我正在使用它,它确实有效。 http://weblogs.asp.net/manishdalal/archive/2008/09/24/prevention-the-first-line-of-defense-with-attach-property-pixie-dust.aspx
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
bool isDigit = e.Key >= Key.D0 && e.Key < Key.D9 || e.Key == Key.NumPad0 || e.Key == Key.NumPad1 || e.Key == Key.NumPad2 || e.Key == Key.NumPad3 || e.Key == Key.NumPad4 || e.Key == Key.NumPad5 || e.Key == Key.NumPad6 ||
e.Key == Key.NumPad7 || e.Key == Key.NumPad8 || e.Key == Key.NumPad9 ||e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Left || e.Key == Key.Right;
if (isDigit) { }
else
e.Handled = true;
}
private void txtbox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.D0 || e.Key == Key.D1 || e.Key == Key.D2 || e.Key == Key.D3 || e.Key == Key.D4 || e.Key == Key.D5 || e.Key == Key.D6 || e.Key == Key.D7 || e.Key == Key.D8 || e.Key == Key.D9 || e.Key == Key.NumPad0 || e.Key == Key.NumPad1 || e.Key == Key.NumPad2 || e.Key == Key.NumPad3 || e.Key == Key.NumPad4 || e.Key == Key.NumPad5 || e.Key == Key.NumPad6 || e.Key == Key.NumPad7 || e.Key == Key.NumPad8 || e.Key == Key.NumPad9)
e.Handled = false;
else
e.Handled = true;
}
它有效:
static bool AltGrIsPressed;
void Numclient_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Alt)
{
AltGrIsPressed = false;
}
}
void Numclient_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Alt)
{
AltGrIsPressed = true;
}
if (Keyboard.Modifiers == ModifierKeys.Shift || AltGrIsPressed == true)
{
e.Handled = true;
}
if (e.Handled == false && (e.Key < Key.D0 || e.Key > Key.D9))
{
if (e.Key < Key.NumPad0 || e.Key > Key.NumPad9)
{
if (e.Key != Key.Back)
{
e.Handled = true;
}
}
}
}
我知道这个问题已经有答案了,但是我没有找到一个能够处理所有特殊情况的合适解决方案,大多数答案都忽略了一些重要的按键,比如Home、End、Tab、Shift+任何按键等等。
因此,我开发了自己的实现,希望能对某些人有所帮助!
public class IntegerTextBox : TextBox
{
/// <summary>
/// To be raised whenever integer value changed
/// </summary>
public event EventHandler ValueChanged;
/// <summary>
/// To restore if the user entered invalid characters
/// </summary>
private int lastSavedValue = 0;
private int lastSelectionStart = 0;
private int lastSelectionLength = 0;
public int IntegerValue
{
get
{
//the default value is 0 if there is no text in the textbox
int value = 0;
int.TryParse(Text, out value);
return value;
}
set
{
if (this.Text.Trim() != value.ToString())
{
Text = value.ToString();
}
}
}
public IntegerTextBox()
: base()
{
this.LostFocus += (sender, e) =>
{
//if the user clears the text the text box and leaves it, set it to default value
if (string.IsNullOrWhiteSpace(this.Text))
IntegerValue = 0;
};
this.Loaded += (sender, e) =>
{
//populate the textbox with Initial IntegerValue (default = 0)
this.Text = this.IntegerValue.ToString();
};
this.TextChanged += (sender, e) =>
{
int newValue = 0;
if (int.TryParse(this.Text, out newValue)) //this will handle most cases like number exceeds the int max limits, negative numbers, ...etc.
{
if (string.IsNullOrWhiteSpace(Text) || lastSavedValue != newValue)
{
lastSavedValue = newValue;
//raise the event
EventHandler handler = ValueChanged;
if (handler != null)
handler(this, EventArgs.Empty);
}
}
else
{
//restore previous number
this.Text = lastSavedValue.ToString();
//restore selected text
this.SelectionStart = lastSelectionStart;
this.SelectionLength = lastSelectionLength;
}
};
this.KeyDown += (sender, e) =>
{
//before every key press, save selection start and length to handle overwriting selected numbers
lastSelectionStart = this.SelectionStart;
lastSelectionLength = this.SelectionLength;
};
}
}
上述代码有一个缺点,TextChanged事件会频繁触发,但由于我们需要一个整数文本框,因此我们可以依赖ValueChanged事件!
扩展普通的Silverlight文本框控件。将此代码添加到扩展的TextBox类中:
string nums = "1234567890";
string lastText = "";
int lastSelStart = 0;
protected override void TextChanged(object sender, TextChangedEventArgs e)
{
if(!nums.Contains(this.Text.Substring(this.Text.Length -1)))
{
this.Text = lastText;
this.SelectionStart = lastSelStart;
return;
}
lastText = this.Text;
lastSelStart = this.SelectionStart;
}