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;
}
}
}
}