C# 如何在 Silverlight 中创建数字文本框?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/268207/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create a numeric textbox in Silverlight?
提问by Mark Ingram
As the title says really. I've had a look at inheriting from TextBox, but the only sensible override was "OnKeyDown", but that just gives me a key from the Key enum (with no way to use Char.IsNumeric()).
正如标题所说的那样。我看过从 TextBox 继承,但唯一合理的覆盖是“OnKeyDown”,但这只是从 Key 枚举中给我一个键(无法使用 Char.IsNumeric())。
采纳答案by Tim Heuer
Take a look at NumericUpDown in the Toolkit http://codeplex.com/Silverlightand maybe you can use that or look at the source to implement your own numeric textbox.
看看 Toolkit http://codeplex.com/Silverlight中的 NumericUpDown,也许您可以使用它或查看源代码来实现您自己的数字文本框。
回答by jgarza
Take a look at this one, it uses an attached property over the textbox. I am using it and it does work. http://weblogs.asp.net/manishdalal/archive/2008/09/24/prevention-the-first-line-of-defense-with-attach-property-pixie-dust.aspx
看看这个,它在文本框上使用附加属性。我正在使用它,它确实有效。 http://weblogs.asp.net/manishdalal/archive/2008/09/24/prevention-the-first-line-of-defense-with-attach-property-pixie-dust.aspx
回答by Nidhal
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;
}
}
}
}
回答by amurra
I took Nidhal's suggested answer and edited it a bit to handle the shift case for the characters above the digits (ie. !@#$%^&*()) since that solution will still allow those characters in the textbox.
我接受了 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;
}
}
}
}
回答by Emy
It works:
有用:
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;
}
}
}
}
回答by Nauman
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;
}
回答by Ross Brigoli
Extend the normal Silverlight Textbox control. Add this code inside the extended TextBox class:
扩展正常的 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;
}
回答by Sameh Deabes
I know it has been answered, but I found no proper solution that handles all special cases, most answers here swallows some important keys like Home, End, Tab, Shift+ any thing, ..etc.
我知道已经回答了,但我没有找到处理所有特殊情况的正确解决方案,这里的大多数答案都吞下了一些重要的键,如 Home、End、Tab、Shift+ 任何东西等等。
So, I developed my own implementation as it may help somebody!
所以,我开发了自己的实现,因为它可能对某人有所帮助!
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;
};
}
}
The above code has a single disadvantage, TextChanged event will be raised frequently, but since we need an integer
textbox, then we can rely on ValueChanged
instead!
上面的代码有一个缺点,TextChanged 事件会频繁引发,但是既然我们需要一个integer
文本框,那么我们可以依靠ValueChanged
!
回答by Jerry Nixon
Why is everyone not doing the hard work of just handling them all?
为什么不是每个人都在努力处理它们?
Here (this is perfection):
在这里(这是完美的):
<TextBox KeyDown="TextBox_KeyDown" />
private void TextBox_KeyDown(object sender, KeyEventArgs e)
{
var _Letter = string.Empty;
switch (e.Key)
{
case Key.A: _Letter = "A"; break;
case Key.Add: _Letter = "+"; break;
case Key.Alt: break;
case Key.B: _Letter = "B"; break;
case Key.Back: break;
case Key.C: _Letter = "C"; break;
case Key.CapsLock: break;
case Key.Ctrl: break;
case Key.D: _Letter = "D"; break;
case Key.D0: _Letter = "0"; break;
case Key.D1: _Letter = "1"; break;
case Key.D2: _Letter = "2"; break;
case Key.D3: _Letter = "3"; break;
case Key.D4: _Letter = "4"; break;
case Key.D5: _Letter = "5"; break;
case Key.D6: _Letter = "6"; break;
case Key.D7: _Letter = "7"; break;
case Key.D8: _Letter = "8"; break;
case Key.D9: _Letter = "9"; break;
case Key.Decimal: _Letter = "."; break;
case Key.Delete: break;
case Key.Divide: _Letter = "/"; break;
case Key.Down: break;
case Key.E: _Letter = "E"; break;
case Key.End: break;
case Key.Enter: break;
case Key.Escape: break;
case Key.F: _Letter = "F"; break;
case Key.F1: break;
case Key.F10: break;
case Key.F11: break;
case Key.F12: break;
case Key.F2: break;
case Key.F3: break;
case Key.F4: break;
case Key.F5: break;
case Key.F6: break;
case Key.F7: break;
case Key.F8: break;
case Key.F9: break;
case Key.G: _Letter = "G"; break;
case Key.H: _Letter = "H"; break;
case Key.Home: break;
case Key.I: _Letter = "I"; break;
case Key.Insert: break;
case Key.J: _Letter = "J"; break;
case Key.K: _Letter = "K"; break;
case Key.L: _Letter = "L"; break;
case Key.Left: break;
case Key.M: _Letter = "M"; break;
case Key.Multiply: _Letter = "*"; break;
case Key.N: _Letter = "N"; break;
case Key.None: break;
case Key.NumPad0: _Letter = "0"; break;
case Key.NumPad1: _Letter = "1"; break;
case Key.NumPad2: _Letter = "2"; break;
case Key.NumPad3: _Letter = "3"; break;
case Key.NumPad4: _Letter = "4"; break;
case Key.NumPad5: _Letter = "5"; break;
case Key.NumPad6: _Letter = "6"; break;
case Key.NumPad7: _Letter = "7"; break;
case Key.NumPad8: _Letter = "8"; break;
case Key.NumPad9: _Letter = "9"; break;
case Key.O: _Letter = "O"; break;
case Key.P: _Letter = "P"; break;
case Key.PageDown: break;
case Key.PageUp: break;
case Key.Q: _Letter = "Q"; break;
case Key.R: _Letter = "R"; break;
case Key.Right: break;
case Key.S: _Letter = "S"; break;
case Key.Shift: break;
case Key.Space: _Letter = " "; break;
case Key.Subtract: _Letter = "-"; break;
case Key.T: _Letter = "T"; break;
case Key.Tab: break;
case Key.U: _Letter = "U"; break;
case Key.Unknown: break;
case Key.Up: break;
case Key.V: _Letter = "V"; break;
case Key.W: _Letter = "W"; break;
case Key.X: _Letter = "X"; break;
case Key.Y: _Letter = "Y"; break;
case Key.Z: _Letter = "Z"; break;
default: break;
}
var _Text = (sender as TextBox).Text + _Letter;
double _Double;
e.Handled = !double.TryParse(_Text, out _Double);
}
}
}
回答by xidius
Visit http://www.dataartist.net/blog/post/Silverlight-Behavior-Modifications-13-NumericOnlyBehavior.aspxor use TextBox behavior as below
访问http://www.dataartist.net/blog/post/Silverlight-Behavior-Modifications-13-NumericOnlyBehavior.aspx或使用如下的 TextBox 行为
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;
}
}
}