我尝试在这里创建自己的数字文本框是我的代码:
public class NumericTextBox : TextBox
{
public NumericTextBox()
: base()
{
this.Text = "0";
}
private void HandleKeyEvent(KeyEventArgs e)
{
e.Handled = true;
if ((Keyboard.Modifiers & ModifierKeys.Alt) != 0)
{
return;
}
if (e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Left || e.Key == Key.Right ||
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 if ((e.Key == Key.Subtract || (e.Key == Key.Unknown && e.PlatformKeyCode == 189)) && base.SelectionStart == 0 && (base.Text.Length == 0 || base.Text[0] != '-'))
{
e.Handled = false;
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
HandleKeyEvent(e);
base.OnKeyDown(e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
HandleKeyEvent(e);
base.OnKeyUp(e);
}
}
一切都像假设一样,但是如果你按alt和一些数字它会创建对应于数字的ascii符号..有没有办法阻止“alt +数字组合? 似乎只是输入了alt + key而没有抛出OnKeyUp或OnKeyDown ...
答案 0 :(得分:2)
我通过使用TextChanged事件来实现它是我的代码...
public class NumericTextBox : TextBox
{
int value;
public NumericTextBox()
: base()
{
this.Text = "0";
this.TextChanged += new TextChangedEventHandler(NumericTextBox_TextChanged);
}
void NumericTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
int selectionStart = base.SelectionStart;
bool changed = false;
List<char> charList = new List<char>();
for (int i = 0; i < base.Text.Length; i++)
{
if (IsValidChar(base.Text[i], i))
{
charList.Add(base.Text[i]);
}
else
{
if (selectionStart >= i)
{
selectionStart--;
}
changed = true;
}
}
if (changed)
{
string text = new string(charList.ToArray());
this.Text = text;
this.SelectionStart = selectionStart;
}
int newValue;
if (!int.TryParse(this.Text, out newValue))
{
this.Text = value.ToString();
this.SelectionStart = this.Text.Length;
}
else
{
value = newValue;
}
}
private bool IsValidChar(char c, int index)
{
return ((c == '-' && index == 0) || c == '0' || c == '1' || c == '2' || c == '3' || c == '4' || c == '5' || c == '6' || c == '7' || c == '8' || c == '9');
}
private void HandleKeyEvent(KeyEventArgs e)
{
e.Handled = true;
if ((Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control)
{
e.Handled = false;
}
if (e.Key == Key.Back || e.Key == Key.Delete || e.Key == Key.Left || e.Key == Key.Right ||
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 if ((e.Key == Key.Subtract || (e.Key == Key.Unknown && e.PlatformKeyCode == 189)) && base.SelectionStart == 0 && (base.Text.Length == 0 || base.Text[0] != '-'))
{
e.Handled = false;
}
}
protected override void OnKeyDown(KeyEventArgs e)
{
HandleKeyEvent(e);
base.OnKeyDown(e);
}
protected override void OnKeyUp(KeyEventArgs e)
{
HandleKeyEvent(e);
base.OnKeyUp(e);
}
}
答案 1 :(得分:2)
这是一个替代方案,只需要附加属性和以下代码。 首先,代码:
public enum InputType
{
PositiveInteger,
PositiveDecimal,
PositiveNullableInteger,
PositiveNullableDecimal,
}
public static class Input
{
public static readonly DependencyProperty TypeProperty =
DependencyProperty.RegisterAttached("Type", typeof(InputType), typeof(TextBox),
new PropertyMetadata(default(InputType), OnTypeChanged));
public static void SetType(TextBox element, InputType value)
{
element.SetValue(TypeProperty, value);
}
public static InputType GetType(TextBox element)
{
return (InputType)element.GetValue(TypeProperty);
}
private class TextSelection
{
public string Text { get; private set; }
public int SelectionStart { get; private set; }
public int SelectionLength { get; private set; }
public TextSelection(string text, int selectionStart, int selectionLength)
{
Text = text;
SelectionStart = selectionStart;
SelectionLength = selectionLength;
}
}
private static readonly DependencyProperty PreviousTextSelectionProperty =
DependencyProperty.RegisterAttached("PreviousTextSelection", typeof(TextSelection),
typeof(TextBox), new PropertyMetadata(default(TextSelection)));
private static void SetPreviousTextSelection(TextBox element, TextSelection value)
{
element.SetValue(PreviousTextSelectionProperty, value);
}
private static TextSelection GetPreviousTextSelection(TextBox element)
{
return (TextSelection)element.GetValue(PreviousTextSelectionProperty);
}
private static void OnTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (UIApplication.DesignMode)
return;
var textBox = (TextBox)d;
textBox.TextChanged += OnTextChanged;
textBox.SelectionChanged += OnSelectionChanged;
}
/// <summary>
/// Determines whether the specified text is valid.
/// </summary>
/// <param name="text">The text.</param>
/// <param name="inputType">Type of the input.</param>
/// <returns>
/// <c>true</c> if the specified text is valid; otherwise, <c>false</c>.
/// </returns>
private static bool IsValid(string text, InputType inputType)
{
switch (inputType)
{
case InputType.PositiveInteger:
int i;
return int.TryParse(text, out i);
case InputType.PositiveDecimal:
decimal d;
return decimal.TryParse(text, out d) && d >= 0;
case InputType.PositiveNullableInteger:
return text.IsNullOrEmpty() || IsValid(text, InputType.PositiveInteger);
case InputType.PositiveNullableDecimal:
return text.IsNullOrEmpty() || IsValid(text, InputType.PositiveDecimal);
default:
throw new ArgumentOutOfRangeException("inputType");
}
}
private static void OnTextChanged(object sender, TextChangedEventArgs e)
{
var textBox = (TextBox)sender;
var inputType = GetType(textBox);
if (IsValid(textBox.Text, inputType))
{
SetPreviousTextSelection(textBox, new TextSelection(textBox.Text, textBox.SelectionStart, textBox.SelectionLength));
}
else
{
var textSelection = GetPreviousTextSelection(textBox);
if (textSelection == null)
{
textBox.Text = "";
}
else
{
textBox.Text = textSelection.Text;
textBox.SelectionStart = textSelection.SelectionStart;
textBox.SelectionLength = textSelection.SelectionLength;
}
}
}
private static void OnSelectionChanged(object sender, RoutedEventArgs e)
{
var textBox = (TextBox)sender;
SetPreviousTextSelection(textBox, new TextSelection(textBox.Text, textBox.SelectionStart, textBox.SelectionLength));
}
}
然后在你的xaml代码中使用它(“ui:”名称空间需要解析,但是嘿,你还需要做你的作业:)):
<TextBox Text="{Binding MyText, Mode=TwoWay}" ui:Input.Type="PositiveNullableDecimal" />
基本上,扩展器会记忆最后一个有效状态(文本+选择),如果新结果无效则还原它。 枚举InputType当然可以扩展。
答案 2 :(得分:1)
有没有办法阻止“alt +数字组合?
不是真的。我的建议是不要打扰,看看会发生什么。
TBH如果你真的想要构建一个数字输入控件,你不应该从TextBox
派生。您将从Control
派生并将TextBox放在新控件的默认控件模板中。
事实上,说实话,我刚刚使用了Toolkit中的NumericUpDown。
答案 3 :(得分:0)
您是否只是想阻止非数字文本输入? this blog post中描述的另一种方法是创建一个文本框过滤器,可以将其作为附加的依赖项属性添加到普通TextBox中。无论哪种方式,您仍然需要在输入数据后对其进行验证,因为用户可能会粘贴无效数据。
答案 4 :(得分:0)
我知道它已被回答,但我在这里贴了a more elegant answers(这可能对某人有所帮助!)
答案 5 :(得分:-1)