Windows Phone 72012. 2. 3. 17:21

기본 PasswordBox 컨트롤…

일단 TextBox의 기능을 많이 제거 하였으며

무엇보다. Sealed로 되어 있어서 상속을 못한다!!!

그래서 상속받아서 나만의 컨트롤을 만들수가 없고

더 중요한건!!!

InputScope를 지원안한다는거… 어휴..

나는 Number 만 쓰는 PasswordBox를 만들고 싶었지만

윈폰에서 제공 되지 않아서 이리저리 찾아보았지만 단한개의 Numberic PasswordBox가 없었다.!!!

이럴수가?

할수없이 컨트롤을 만들었다 하지만 사용하기는 쉽지 않을것 같다.

빨리 만들려고 UserControl로 만들었다.

public partial class NumbericPasswordCtl : UserControl
   {
       StringBuilder _fakeString;

       public NumbericPasswordCtl()
       {
           InitializeComponent();
           _fakeString = new StringBuilder();
           xRealTB.Opacity = 0;
           xRealTB.KeyUp += new System.Windows.Input.KeyEventHandler(xRealTB_KeyUp);
       }

       private void xRealTB_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
       {
           if (e.Key == System.Windows.Input.Key.Unknown)
               return;

           if (e.Key == System.Windows.Input.Key.Back)
           {
               if (_fakeString.Length <= 0)
                   return;

               _fakeString.Remove(_fakeString.Length - 1, 1);
           }
           else
           {
               _fakeString.Append("*");
           }
           xFakeTB.Text = _fakeString.ToString();
       }
   }
 
    <Grid x:Name="LayoutRoot">
        <TextBlock IsHitTestVisible="False" x:Name="xFakeTB" Foreground="White" FontSize="56" />
        <TextBox InputScope="Number" x:Name="xRealTB"/>
    </Grid>

원리는 InputScope가 지원되는 TextBox위에 TextBlock를 덮어 씌우고 IsHitTestVisible을 false로 하였다.

그래서 TextBox에 숫자를 입력하지만 사용자가 보이는것은 TextBlock에 * 을 보게 될것이다.

이건 패스워드box에 워터마크를 추가하는것에 흰트를 얻었는데

Toolkit에서 지원하는 TextBox에는 Hint를 제공해주지만 PasswordBox는 지원해주지 않는다.

PasswordBox 워터마크도 비슷한 방법으로 사용할수 있다.

참고 : http://damianblog.com/2011/01/21/wp7-password-watermark/

Posted by 동동(이재동)
Windows Phone 72010. 10. 4. 17:21

현제 기본적으로 inputScop를 지원하는 유일한 Numberic 키패드는 TelephoneNumber이다.(머 추후 업데이트 되겠지 )

 

먼저 Number키패드에는 . 만 있는게 아니라 ‘ 라든지 있다.

 

나는 . 만 입력되게 하고 싶었지만 아예 .키가 동작을 하지 않았다… 더 억울한 상황 ㅠ.ㅠ

 

그래서 TextBox 를 상속받아서 override해서 해결하였다.

 

일단 전체 소스를 보자

 

 
using System.Globalization;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using SalePrice.Views;
using System;
 
namespace SalePrice.Controls
{
    public class FormattedTextBox : TextBox
    {
        public enum NumberType
        {
            Number,
            Double,
            Integer,
            Currency
        };
 
        public string FormattedText
        {
            get { return (string)GetValue(FormattedTextProperty); }
            set { SetValue(FormattedTextProperty, value); }
        }
 
        public static readonly DependencyProperty FormattedTextProperty =
            DependencyProperty.Register("FormattedText", typeof(string), typeof(FormattedTextBox), new PropertyMetadata(string.Empty));
 
        public double Number
        {
            get { return (double)GetValue(NumberProperty); }
            set { SetValue(NumberProperty, value); }
        }
 
        public static readonly DependencyProperty NumberProperty =
            DependencyProperty.Register("Number", typeof(double), typeof(FormattedTextBox), new PropertyMetadata(double.NaN, onNumberPropertyChanged));
 
        protected static void onNumberPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FormattedTextBox ftb = d as FormattedTextBox;
            ftb.onNumberChanged((double)e.OldValue, (double)e.NewValue);
        }
 
        public NumberType Type
        {
            get { return (NumberType)GetValue(TypeProperty); }
            set { SetValue(TypeProperty, value); }
        }
 
        public static readonly DependencyProperty TypeProperty =
            DependencyProperty.Register("Type", typeof(NumberType), typeof(FormattedTextBox), new PropertyMetadata(NumberType.Double, onTypePropertyChanged));
 
        protected static void onTypePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            FormattedTextBox ftb = d as FormattedTextBox;
            ftb.onTypeChanged((NumberType)e.OldValue, (NumberType)e.NewValue);
        }
 
        private Regex _regex = null;
        private string _lastSuccess = string.Empty;
        private int _prevPos = 0;
 
        public FormattedTextBox()
        {
            DefaultStyleKey = typeof(FormattedTextBox);
            TextChanged += onTextChanged;
            InputScope = new InputScope();
            //InputScope.Names.Add(new InputScopeName(){ NameValue= InputScopeNameValue.CurrencyAmount});
            InputScope.Names.Add(new InputScopeName() { NameValue = InputScopeNameValue.TelephoneNumber });
 
        }
 
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            setType(Type);
            updateFormattedText();            
       }
 
        protected override void OnManipulationCompleted(ManipulationCompletedEventArgs e)
        {
            base.OnManipulationCompleted(e);
            this.Focus();
        }
 
        private void setType(NumberType type)
        {
            switch (type)
            {
                case NumberType.Double:
                case NumberType.Currency:
                    _regex = new Regex(@"^\d+\.?\d*?$");
                    //_regex = new Regex(@"^(((\d{1,3})(,\d{3})*)|(\d+))(.\d+)?$");
                    break;
                case NumberType.Number:
                case NumberType.Integer:
                    _regex = new Regex(@"^\d+$");
                    //_regex = new Regex(@"^\d+$");                    
                    break;
            }
        }
 
        private void updateFormattedText()
        {
            if (string.IsNullOrEmpty(Text) == true || _regex == null)
                return;
 
            if (_regex.Match(Text).Success == false)
            {
                Text = _lastSuccess;
                SelectionStart = _prevPos;
            }
 
            double num = 0;
            double.TryParse(Text, out num);
 
            switch (Type)
            {
                case NumberType.Double:
                    {
                        Number = num;
                        FormattedText = Text;
                    }
                    break;
                case NumberType.Integer:
                    {
                        Number = (int)num;
                        FormattedText = Text;
                    }
                    break;
                case NumberType.Currency:
                    {
                        Number = num;
                        //FormattedText = string.Format("{0:C}", Number);
                        FormattedText = string.Format("{0:N}", Number);
                    }
                    break;
            }            
        }
 
        private void onTextChanged(object sender, TextChangedEventArgs e)
        {
            if (string.IsNullOrEmpty(Text) == true)
            {
                Number = 0;
                SelectAll();
                SelectionStart = 0;
            }
            updateFormattedText();
        }
        
 
        protected virtual void onNumberChanged(double oldValue, double newValue)
        {
            string old = Text;         
            Text = newValue.ToString();
 
            if (Text != old)
            {
                SelectionStart = _prevPos;
            }
        }
 
        protected virtual void onTypeChanged(NumberType oldValue, NumberType newValue)
        {
            setType(newValue);
            updateFormattedText();
        }
 
        protected override void OnGotFocus(RoutedEventArgs e)
        {
            base.OnGotFocus(e);
 
            SelectAll();
            SelectionStart = 0;
        }
 
       
        protected override void OnKeyDown(KeyEventArgs e)
        {            
            _lastSuccess = Text;
            _prevPos = SelectionStart;
           
            switch (e.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:
                case Key.NumPad0:
                case Key.NumPad1:
                case Key.NumPad2:
                case Key.NumPad3:
                case Key.NumPad4:
                case Key.NumPad5:
                case Key.NumPad6:
                case Key.NumPad7:
                case Key.NumPad8:
                case Key.NumPad9:
                case Key.Decimal:
                case Key.Delete:
                case Key.Back:
                case Key.Left:
                case Key.Right:
                case Key.Enter:                
                case Key.Tab:
                    {
                        base.OnKeyDown(e);
                    }
                    break;
                default:
                    {
                        //"."키의 keycode로 구분해서 사용 가능하게 만든다.
                        if (e.PlatformKeyCode == 190)
                        {
                            base.OnKeyDown(e);
                        }
                        else
                        {
                            e.Handled = true;
                        }                        
                    }
                    break;
            }
        }
    }
}
 


key 다운에 보면 주석으로 달아놓았다 ㅋㅋ

Posted by 동동(이재동)