为什么TextBox属性MaxLength不适用于自定义TextBox?

时间:2013-07-23 10:43:22

标签: windows-phone-7.1

我想要一个带数字输入范围的密码框,不幸的是PasswordBox不允许开发人员指定数字InputScope。 所以我通过自定义TextBox实现了这个目标。 我的代码在这里,MainPage.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.Text.RegularExpressions;

namespace PaswwordBoxwithNumericInput
{
    public partial class MainPage : PhoneApplicationPage
    {
        // Constructor
        public MainPage()
        {
            InitializeComponent();

        }

    string _enteredPasscode = "";
    string _passwordChar = "*";

    private void PasswordTextBox_KeyUp(object sender, KeyEventArgs e)
    {
        //modify new passcode according to entered key
        _enteredPasscode = GetNewPasscode(_enteredPasscode, e.PlatformKeyCode);

        //replace text by *
        PasswordTextBox.Text = Regex.Replace(_enteredPasscode, @".", _passwordChar);

        //take cursor to end of string
        TextBox t = new TextBox();
       // PasswordTextBox.SelectionStart = t.Text.Length;
    }
    private string GetNewPasscode(string oldPasscode, int keyId)
    {
        string newPasscode = string.Empty;
        switch (keyId)
        {
            case 233:
                newPasscode = oldPasscode;
                break;
            case 8:
                //back key pressed
                if (oldPasscode.Length > 0)
                    newPasscode = oldPasscode.Substring(0, oldPasscode.Length - 1);
                break;
            case 190:
                // . pressed
                newPasscode = oldPasscode;
                break;
            default:
                //Number pressed
                newPasscode = oldPasscode + (keyId - 48);
                break;
        }
        return newPasscode;
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        string str = _enteredPasscode;
    }
}

}

和MainPage.xaml在这里

<phone:PhoneApplicationPage 
    x:Class="PaswwordBoxwithNumericInput.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
    FontFamily="{StaticResource PhoneFontFamilyNormal}"
    FontSize="{StaticResource PhoneFontSizeNormal}"
    Foreground="{StaticResource PhoneForegroundBrush}"
    SupportedOrientations="Portrait" Orientation="Portrait"
    shell:SystemTray.IsVisible="True">

    <!--LayoutRoot is the root grid where all page content is placed-->
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
        </StackPanel>

        <!--ContentPanel - place additional content here-->
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
            <TextBox Height="72" HorizontalAlignment="Left" Margin="42,189,0,0" Name="PasswordTextBox"  VerticalAlignment="Top" Width="374"  MaxLength="6" InputScope="Number"  KeyUp="PasswordTextBox_KeyUp">



            </TextBox>
            <Button Content="Button" Height="72" HorizontalAlignment="Left" Margin="221,436,0,0" Name="button1" VerticalAlignment="Top" Width="160" Click="button1_Click" />
        </Grid>

    </Grid>

    <!--Sample code showing usage of ApplicationBar-->
    <!--<phone:PhoneApplicationPage.ApplicationBar>
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>
            <shell:ApplicationBar.MenuItems>
                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>
                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>
            </shell:ApplicationBar.MenuItems>
        </shell:ApplicationBar>
    </phone:PhoneApplicationPage.ApplicationBar>-->

</phone:PhoneApplicationPage>

一切都很好,除了两个问题。 1)我已将TextBox的MaxLength设置为修复号,但它不起作用(我可以将TextBox的文本放在6以上)。 2)当我在TextBox上打字时,光标没有移动(它固定在第一个位置)。从用户的角度来看,这并不好。 请帮我解决这两个问题。

3 个答案:

答案 0 :(得分:1)

试试这个,它会按你的意愿工作。适用于Windows Phone的带有MaxLength的PasswordBox。

int maxLength = 4;
string _enteredPasscode = "";
string _passwordChar = "*";

    private void PasswordTextBox_KeyUp(object sender, KeyEventArgs e)
    {
        if (PasswordTextBox.Text.Length > 4)
        {
            // Set Text to previous text of length 4
            PasswordTextBox.Text = System.Text.RegularExpressions.Regex.Replace(_enteredPasscode, @".", _passwordChar);
            //take cursor to end of string
            PasswordTextBox.SelectionStart = PasswordTextBox.Text.Length;

            e.Handled = false;
            return;
        }

        //modify new passcode according to entered key
        _enteredPasscode = GetNewPasscode(_enteredPasscode, e);
        //replace text by *
        PasswordTextBox.Text = System.Text.RegularExpressions.Regex.Replace(_enteredPasscode, @".", _passwordChar);
        //take cursor to end of string
        PasswordTextBox.SelectionStart = PasswordTextBox.Text.Length;
    }

        private string GetNewPasscode(string oldPasscode, System.Windows.Input.KeyEventArgs keyEventArgs)
    {
        string newPasscode = string.Empty;
        switch (keyEventArgs.Key)
        {
            case Key.D0:
            case Key.D1:
            case Key.D2:
            case Key.D3:
            case Key.D4:
            case Key.D5:
            case Key.D6:
            case Key.D7:
            case Key.D8:
            case Key.D9:
                newPasscode = oldPasscode + (keyEventArgs.PlatformKeyCode - 48);
                break;
            case Key.Back:
                if (oldPasscode.Length > 0)
                    newPasscode = oldPasscode.Substring(0, oldPasscode.Length - 1);
                break;
            default:
                //others
                newPasscode = oldPasscode;
                break;
        }
        return newPasscode;
    }

答案 1 :(得分:0)

您只能为TextBox指定输入范围。密码盒无法使用此功能的原因是

The input scope gives the clear idea about the character type. Hence hacker can easily identify that your password consist of only numeric and that makes him to know your password easily.

答案 2 :(得分:0)

您必须使用此代码

 private void txtCardName_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
    {
        _enteredPasscode = Utility.GetNewPasscode(_enteredPasscode, e);
        if (!string.IsNullOrEmpty(_enteredPasscode) && _enteredPasscode.Length < 13)
        {
            TextBoxPinCode.Text = Regex.Replace(_enteredPasscode, @".", _passwordChar);
            TextBoxPinCode.SelectionStart = TextBoxPinCode.Text.Length;    
        }

    }

我们必须检查Key_Up事件,检查lenght _enterPasscode是否小于你的限制,