Silverlight数字文本框?

时间:2009-12-29 21:58:52

标签: c# silverlight

我尝试在这里创建自己的数字文本框是我的代码:

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 ...

6 个答案:

答案 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)

短而甜 - Alt键的处理程度低于程序。

This文章更详细地介绍了这个问题,而this链接提供了一些可以帮助您的c ++代码,如果您真的想解决这个问题。