的Windows Phone 8.1文本字符virtualKey验证 [英] windows phone 8.1 textbox character virtualKey validation

查看:354
本文介绍了的Windows Phone 8.1文本字符virtualKey验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

IM develeoping的Windows Phone 8.1的应用程序。
在一个文本框,我想阻止用户输入任何非数字只信[0-9]

im develeoping windows phone 8.1 app. In a textbox I want to prevent the user from inputting any non-digital letter only [0-9].

因此,这里是我的代码:

So here is my code:

 private void NumKeyDown(object sender, KeyRoutedEventArgs e)
        {

           bool isNumber = (e.Key == Windows.System.VirtualKey.Number0 ||
                 e.Key == VirtualKey.Number1 ||
                 e.Key == VirtualKey.Number2 ||
                 e.Key == VirtualKey.Number3 ||
                 e.Key == VirtualKey.Number4 ||
                 e.Key == VirtualKey.Number5 ||
                 e.Key == VirtualKey.Number6 ||
                 e.Key == VirtualKey.Number7 ||
                 e.Key == VirtualKey.Number8 ||
                 e.Key == VirtualKey.Number9 ||
                 e.Key == VirtualKey.Back);

            CoreVirtualKeyStates shiftState = Window.Current.CoreWindow.GetKeyState(VirtualKey.Shift);


            bool shiftIsNotDown = true;
            if ((shiftState & CoreVirtualKeyStates.Down) == CoreVirtualKeyStates.Down)
                shiftIsNotDown = false;

            e.Handled = !(isNumber && shiftIsNotDown);

        }



它的工作原理,但有两个主要缺陷:

it works but there are two major flaws :

1,也接受移入字符(即@#$%^&安培;!*)。而不是想

1- it also accept the shifted-characters( i.e !@#$%^&*) while that is not wanted.

2 - 当我启动应用程序的文本框充满了一个数字。我可以输入任何数字或字符(!@#$%^),我也可以删除使用退格。在此期间, ShiftState 。然而,一旦我使用退格键删除文本框中的所有内容 ShiftState 更改为[锁定|向下]和我变得无法在文本框中输入任何内容。

2- when I start the app the textbox is filled with a number. I can input any number or characters(!@#$%^), also I can delete using the BACKSPACE. during this time the ShiftState is NONE. However once I delete all content in the textbox using the BACKSPACE the ShiftState changes to [ locked | Down ] and I become unable to input anything in that text box.

请注意,我从来没有接触换档按钮!

notice that i never touch the shift button !

我在哪里错在这里?

更新

我发现,使用刷卡功能将输入文字的字母,而不会触发KeyDown事件我申请:(

I discovered that using the swipe feature will input texts letters without triggering the keyDown event I was applying :(

任何帮助表示赞赏

推荐答案

好吧,我会尽力回答的基础上我这里收到的根据的研究我做的最后几天就反应了这个问题。答案将是两节[旁注 - 解]

Ok, I will try to answer this question based on the responses I received here and based on the research I did for the last couple of days. answer will be two sections [ Side Notes - solution ]

您可以跳到(解决方案部分),如果你不感兴趣,我发现有趣的分享问题的细节与读者

You may jump to (Solution section )if you are not interested in the details of the problems i found interesting to share with readers

旁注:

我已经注意到了以下问题

I have noticed the following problems


  1. 最重要的是,窗口8.1和XAML和WinRT的
    文档是非常差,几乎没有用武之地。我希望有人
    微软WinRT的团队正在读这一点。除非他们在做
    这个目的上最给力的开发商去C ++。

  1. the most important is that window 8.1 and xaml and winRT documentation is extremely poor, and almost useless. I hope someone from Microsoft winRT team is reading this. Unless they are doing this on purpose to force most of the developers to go to C++.

有关测试应用程序。我用了3 [不同]输入法。如下图:

regarding testing my application. I used 3 [[different]] input methods. as the following picture :

和结果是不同的,incosistant与KeyDown事件如下:

and the result was different and incosistant with the KeyDown event as follow :

让我以为我想要输入的字符(安培)

let me assume that I want to input the character (&)


    模拟器键盘上的
  • :KEYDOWN eventArg e.Key = Number7 。 KeyDown事件会触发两次:

  • 电脑触摸键盘上的
  • 。在
    首次e.Key代码将移位,并且在第二KEYDOWN
    事件e.Key将Number7

  • 物理键盘上ofcourse 2 KEYDOWN事件将触发BEC。
    你必须首先按shift然后Number7得到(安培)

我也注意到了物理键盘上。无论哪个转向按(即右侧或左侧)KeyDown事件 e.Key 将显示 LeftShift

also I noticed on the physical keyboard that regardless of which shift you press (i.e. right or left) the KeyDown event e.Key will show LeftShift !!

我不知道这是否是特殊情况,我的电脑键盘,但所有这些研究结果表明,KEYDOWN是不是真的值得信赖和缺乏文档在这里

I don't know if this was special case to my computer keyboard , but all these findings are to show that keyDown is not really trustable and documentation is lacking here

另一种发现我注意到,我无法控制:

Also another finding I noticed that I couldn't control:


  • wheneve你一个空的文本框切换按钮将
    进入的锁定状态对焦(开始你一个资本
    字母句)。所以任何keyDown事件先触发Shift键,那么你按下
    信。如果你不知道
    吧,这可能混淆你。

我要感谢@Bryan树桩,连续服用我到微软链接的 MSFT论坛这给我的重要信息,了解情况:

I would like to thank @Bryan Stump, for taking me to the microsoft link MSFT Forum that showed me important information to understand the situation:

?跟踪的KeyUp和的KeyDown作为湿婆的代码提示将为
有限的情况下工作,但不是全部。例如,它不会与墨水或工作(我
认为)IME输入。这也使得有关键盘的假设布局
这不适用于所有键盘,除非你可以限制到非常具体的
的要求,基本方案为
的唯一方法成功地限制了输入是事后这样做。罗布·卡普兰
[MSFT]

"Tracking KeyUp and KeyDown as Shiva's code suggests will work for limited cases, but not all. For example, it won't work with ink or (I think) IME input. It also makes assumptions about keyboard layout which are not valid for all keyboards. Unless you can limit your requirements to very specific, basic scenarios the only way to successfully limit the input is to do so after the fact." Rob Caplan [MSFT]

这环节向我保证,只有缴费的办法就是接受该字符那么,如果将其删除不相适应您的验证,因此报价:在事后往往做不到。

This link assured me that the only avaiable way is to accept the character then remove it if not suiting your validation, hence the quote :"to do so after the fact".

最后我想感谢@Hans帕桑特他说把我简短的注释在正确的轨道:

and finally I would like to thank @Hans Passant for his short comment that put me on the right track:

使用CoreWindow.CharacterReceived而不是

"Use CoreWindow.CharacterReceived instead".

之后,我开始搜索,唯一的好榜样,我发现关于CoreWindow.CharacterReceived上的计算器

after that I started to search and the only good example I found regarding the CoreWindow.CharacterReceived is on StackOverflow

和从那里我开始了我的解决方案如下。

and from there I started my solution as follow.

解决方案:

简介:


  • 第一:你不能拦截的性格和避免其达到
    文本框

  • First: you can't intercept the character and prevent it from reaching the textbox.

第二:不能使用该keydown或KEYUP事件,知道什么是
字符。你只能有一个想法有关按下的键不
字符导致

Second: you can't use the keyDown or keyUp events to know what is the character. you can only have an idea about the key pressed not the character resulted.

第三:这会给你的性格收到该事件被命名结果
CoreWindow.CharacterReceived,但是请注意,你就会知道结果
字被写入到文本框后。正是在这一点上,你
可以选择接受或删除它

Third: the event that will give you the character recieve is named
"CoreWindow.CharacterReceived", but notice that you will know the
character after it is written to the textbox. it is at this point you can choose to accept it or remove it

第四:由于字符在文本框中收到那么

,来对付它正确的方法是在事件框TextChanged

Fourth: since the character is recieved in the textBox then the
proper way to deal with it is the event textChanged.

第五:也是最重要的;是, CharacterReceived 事件 将美元在单词中的每个字母一个环b $ B火了,这需要特殊的机动和验证

Fifth: and most important; is that the CharacterReceived event will fire in a loop on each letter in the word , and this needs special maneuver and validation

因此基于五事实的伪代码将是:

so based on the Five facts above the pseudoCode will be:

依赖于正则表达式来验证文字和接受。否则,如果输入无效然后恢复 textBox.Text

rely on RegEx to validate the text and accept it; otherwise, if input was invalid then resume the previous state of the textBox.Text

string txtTemp = "";
    private void changedText(object sender, TextChangedEventArgs e)
    {

    Regex regex = new Regex(@"^\d{1,4}$");


string txtToTest = txtNumber.Text;


    if (regex.IsMatch(txtToTest)|| txtNumber.Text=="")
    {
//do nothing 
    }
    else
    {
        txtNumber.Text = txtTemp;
        txtNumber.Select(txtNumber.Text.Length, 0);
    }

//Save the current value to resume it if the next input was invalid
    txtTemp = txtNumber.Text;
}



以上的解决方案适合我的情况,我想确保用户输入只有数字。但也有要确保用户输入特定字母的情况下,你需要根据按下信作出回应!在这种情况下,你需要以下解决方案,它是不完整的,缺乏所有可能的情况下,用户可能输入从剪贴板中(粘贴)一个字母或使用键盘的Swype输入功能。

The above solution suited my case where i want to make sure that user will input numbers only. However there are cases that you want to make sure the user will input specific letter and you need to respond based on the letter pressed !! In such case you will need the following solution which is incomplete and lacking all possible scenario where the user might enter a letter from the clipboard (Paste ) or using the swype functionality of the keyboard.

在这里,你需要控制由字母输入字母为方案解决方案(按琴键):

Here the solution for the scenario where you need to control the input letter by letter (key by key):

1,因为 CoreWindow.CharacterReceived 事件是不特定的textBox(这是窗口/页的事件)。所以你会连线起来时,您的文本框获得焦点。和无线化它,每当你的文本框失去焦点。

1- since CoreWindow.CharacterReceived event is not specific to textBox ( it is window/page event). so you will wire it up whenever your textbox got focus. and unwire it whenever your textbox lose focus.

2 - 听 keyDow事件。每当它被触发时, textBox.Text 值保存到一个临时变量 txtTemp

2- listen to the keyDow event. whenever it is fired, save the textBox.Text value to a temporary variable txtTemp.

3设置一个布尔值,表明收到的字符被接受与否(布尔acceptChange = TRUE )。并利用设置这个布尔的CoreWindow.CharacterReceived事件true或false(接受/不接受)

3- set a boolean indicating that the character recieved is accepted or not (bool acceptChange = true) . and using the CoreWindow.CharacterReceived event set this boolean to true or false (accepted / not accepted)

4-的textChange事件如果布尔acceptChange是真实的,那么就没有。如果布尔acceptChange是假的那么textBox.Text值重置为您KeyDown事件(txtBox.Text = txtTemp)

4- in the textChange event if the bool acceptChange is true, then do nothing. If the bool acceptChange is false then reset the textBox.Text value to the temporary value you saved during the keyDown event ( txtBox.Text = txtTemp )

在这个解决方案,我们可以保存在临时值确保我们只接受我们想要的人物,只有一个很小的问题,其余为以下内容:

with this solution we can make sure that we accept only the character we want, with only one tiny problem remaining as the following:

假设您设置验证规则只接受数字。和textBox.Text =752。
如果用户输入字母v的txtTemp将是752,并为txtBox.Text新值将是752v和textChange情况下,我们的价值恢复到以前的值(即752 )。这是由keydown事件的帮助下完成的。

suppose you set up your validation rules to accept only numbers. and textBox.Text = "752". if the user enter letter "v" the txtTemp will be "752" and the new value for txtBox.Text will be "752v" and on textChange event we will reset the value to the previous value (i.e "752"). this is done by the help of the keydown event.

但如果用户没有输入字母V,但他从其他地方复制并使用了什么粘贴功能则txtBox.Text =752v的新价值,但txtTemp将是75,因为该keydown甚至没有触发捕捉最新txtBox值:(

but what if the user didn't type the letter "v" but he copied it from another place and used the paste function then the new value of txtBox.Text ="752v", but the txtTemp will be "75" because the keYDown even was not triggered to capture the latest txtBox value :(

正是在这里,的textBox中的事件贴的重要性,显示了

it is here that the importance of textBox event "paste" shows up.

所以在我的伪代码第5步:

so step 5 in my pseudocode is:

5在 txtBox.paste 事件确保您通过取消该事件 e.Handled = TRUE;

5- in the txtBox.paste event make sure that you cancel this event by making e.Handled=true;

,现在我来的代码:

//this is critical to wire up the "Window.Current.CoreWindow.CharacterReceived" event when 
//the textBox get focus and to unwire it when the textBox lose focus.
// notice that the whole page is listening not only the textBox

    private void txtBox_GotFocus(object sender, RoutedEventArgs e)
    {
        Window.Current.CoreWindow.CharacterReceived += inputEntered;
    }

    private void txtBox_LostFocus(object sender, RoutedEventArgs e)
    {
        Window.Current.CoreWindow.CharacterReceived -= inputEntered;
    }



// temporary variable for holding the latest textBox value before the textChange event is trigerred
    string txtTemp = "";

    private void txtBox_KeyDown(object sender, KeyRoutedEventArgs e)
    {
        //whenever a key is pressed, capture the latest textBox value
        txtTemp= txtBox.Text;

    }

// this boolean is to be used by the textChanged event to decide to accept changes or not
    bool acceptChange = true;

// here we recieve the character and decide to accept it or not.
    private void inputEntered(CoreWindow sender, CharacterReceivedEventArgs args)
    {
    // reset the bool to true in case it was set to false in the last call
        acceptChange = true;

        Debug.WriteLine("KeyPress " + Convert.ToChar(args.KeyCode)+ "keyCode = "+ args.KeyCode.ToString());
        args.Handled = true;

    //in my case I needed only numeric value and the backSpace button 
        if ((args.KeyCode > 47 && args.KeyCode < 58) || args.KeyCode == 8)
        {
            //do nothing (i.e. acceptChange is still true)
        }
        else
        {
    //set acceptChange to false bec. character is not numeric nor backSpace
            acceptChange = false;
        }
    }



    private void txtBox_TextChanged(object sender, TextChangedEventArgs e)
    {
    //the code here is my validation where I want only 3 digits number with no decimal
        if (txtBox.Text.Length < 4)
        {
            if (acceptChange)
            {
        // do nothing
            }
            else
            {
                txtBox.Text = txtTemp;

        //this is to move the cursor to the end of the text in the textBox
                txtBox.Select(txtBox.Text.Length, 0);
            }
        }
        else
        {
            txtBox.Text = txtTemp;

        //this is to move the cursor to the end of the text in the textBox
            txtBox.Select(txtBox.Text.Length, 0);
        }


    }





// this is for the special case where the user input text using Paste function
    private void txtBox_Paste(object sender, TextControlPasteEventArgs e)
    {
        e.Handled=true;
    }



:)

:)

这篇关于的Windows Phone 8.1文本字符virtualKey验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆