我已设置自定义文本框,除去数字之外的所有内容,然后添加格式以反映phone#format(### - ### - ####)。 Replace方法包含在TextChanged事件中,以便通过鼠标或键盘进行键入或粘贴。格式化是通过LostFocus事件完成的,因为在所有数字都存在之前它无法正确格式化。我的问题是,TextChanged事件在LostFocus事件之后触发,因此所有格式化一旦添加就会被删除。有没有办法绕过这个特定时间的TextChanged?或者更好的方式来组织活动?
namespace CustomTextBoxes
{
public class NumberTextBox : Control
{
}
public class WatermarkTextBox : TextBox
{
public byte bypassEvent = 0;
#region Properties
#region SelectAllOnGotFocus
public static readonly DependencyProperty SelectAllOnGotFocusProperty = DependencyProperty.Register("SelectAllOnGotFocus", typeof(bool), typeof(WatermarkTextBox), new PropertyMetadata(false));
public bool SelectAllOnGotFocus
{
get { return (bool)GetValue(SelectAllOnGotFocusProperty); }
set { SetValue(SelectAllOnGotFocusProperty, value); }
}
#endregion //SelectAllOnGotFocus
#region Watermark
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(object), typeof(WatermarkTextBox), new UIPropertyMetadata(null));
public object Watermark
{
get { return (object)GetValue(WatermarkProperty); }
set { SetValue(WatermarkProperty, value); }
}
#endregion //Watermark
#region WatermarkTemplate
public static readonly DependencyProperty WatermarkTemplateProperty = DependencyProperty.Register("WatermarkTemplate", typeof(DataTemplate), typeof(WatermarkTextBox), new UIPropertyMetadata(null));
public DataTemplate WatermarkTemplate
{
get { return (DataTemplate)GetValue(WatermarkTemplateProperty); }
set { SetValue(WatermarkTemplateProperty, value); }
}
#endregion //WatermarkTemplate
#endregion //Properties
#region Constructors
static WatermarkTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(WatermarkTextBox), new FrameworkPropertyMetadata(typeof(WatermarkTextBox)));
}
#endregion //Constructors
#region Base Class Overrides
protected override void OnGotKeyboardFocus(KeyboardFocusChangedEventArgs e)
{
base.OnGotKeyboardFocus(e);
if (SelectAllOnGotFocus)
SelectAll();
else
SelectionLength = 0;
}
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (!IsKeyboardFocused && SelectAllOnGotFocus)
{
e.Handled = true;
Focus();
}
base.OnPreviewMouseLeftButtonDown(e);
}
#endregion //Base Class Overrides
}
public class DigitBox : WatermarkTextBox
{
#region Constructors
///<summary>
///The default constructor
/// </summary>
public DigitBox()
{
TextChanged += new TextChangedEventHandler(OnTextChanged);
KeyDown += new KeyEventHandler(OnKeyDown);
PreviewKeyDown += new KeyEventHandler(OnPreviewDown);
LostFocus += new RoutedEventHandler(OnLostFocus);
}
#endregion
#region Properties
new public String Text
{
get { return base.Text; }
set
{
base.Text = LeaveOnlyNumbers(value);
}
}
#endregion
#region Functions
public bool IsNumberKey(Key inKey)
{
if (inKey < Key.D0 || inKey > Key.D9)
{
if (inKey < Key.NumPad0 || inKey > Key.NumPad9)
{
return false;
}
}
return true;
}
public bool IsActionKey(Key inKey)
{
return inKey == Key.Delete || inKey == Key.Back || inKey == Key.Tab || inKey == Key.Return;
}
public virtual string LeaveOnlyNumbers(String inString)
{
String tmp = inString;
foreach (char c in inString.ToCharArray())
{
if (!IsDigit(c))
{
tmp = tmp.Replace(c.ToString(), "");
}
}
return tmp;
}
public bool IsDigit(char c)
{
double num;
return (double.TryParse(c.ToString(), out num));
}
public bool IsSpaceKey(Key inKey)
{
if (inKey == Key.Space)
{
return true;
}
return false;
}
#endregion
#region Event Functions
protected virtual void OnKeyDown(object sender, KeyEventArgs e)
{
e.Handled = !IsNumberKey(e.Key) && !IsActionKey(e.Key) && !IsSpaceKey(e.Key);
}
protected virtual void OnTextChanged(object sender, TextChangedEventArgs e)
{
base.Text = LeaveOnlyNumbers(Text);
}
protected virtual void OnPreviewDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Space)
{
e.Handled = true;
}
}
protected virtual void OnLostFocus(object sender, RoutedEventArgs e)
{
base.Text = base.Text;
}
#endregion
}
public class DateBox : DigitBox
{
#region Functions
private bool IsFormattingKey(Key inKey)
{
return inKey == Key.OemPeriod || inKey == Key.OemMinus || inKey == Key.Oem2;
}
public override string LeaveOnlyNumbers(String inString)
{
String tmp = inString;
foreach (char c in inString.ToCharArray())
{
if (!IsDigit(c))
{
//if (c != '/')
//{
// tmp = tmp.Replace(c.ToString(), "");
//}
}
}
return tmp;
}
#endregion
#region Event Functions
protected override void OnKeyDown(object sender, KeyEventArgs e)
{
e.Handled = !IsNumberKey(e.Key) && !IsActionKey(e.Key) && !IsFormattingKey(e.Key) && !IsSpaceKey(e.Key);
}
protected override void OnLostFocus(object sender, RoutedEventArgs e)
{
string content = Text;
char[] contents = content.ToCharArray();
if (content.Length == 8)
{
base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + Text.Substring(4, 4);
}
else if (content.Length == 6)
{
int century = Convert.ToInt32(DateTime.Today.Year.ToString().Substring(2, 2));
string tempCentury = content[4].ToString() + content[5].ToString();
int unknownCentury = Convert.ToInt32(tempCentury);
if (unknownCentury > century + 1)
{
base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + "19" + Text.Substring(4, 2);
}
else base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + "20" + Text.Substring(4, 2);
}
else if (content.Length == 4)
{
base.Text = Text.Substring(0, 1) + "/" + Text.Substring(1, 1) + "/" + Text.Substring(2, 2);
int century = Convert.ToInt32(DateTime.Today.Year.ToString().Substring(2, 2));
string tempCentury = content[4].ToString() + content[5].ToString();
int unknownCentury = Convert.ToInt32(tempCentury);
if (unknownCentury > century + 1)
{
base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + "19" + Text.Substring(4, 2);
}
else base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + "20" + Text.Substring(4, 2);
}
}
#endregion
}
public class PhoneBox : DigitBox
{
private bool IsFormattingKey(Key inKey)
{
return inKey == Key.OemPeriod || inKey == (Key.LeftShift | Key.D9) || inKey == (Key.RightShift | Key.D9) || inKey == (Key.LeftShift | Key.D0) ||
inKey == (Key.RightShift | Key.D0);
}
public override string LeaveOnlyNumbers(String inString)
{
String tmp = inString;
foreach (char c in inString.ToCharArray())
{
if (!IsDigit(c))
{
tmp = tmp.Replace(c.ToString(), "");
}
}
return tmp;
}
#region Event Functions
protected override void OnKeyDown(object sender, KeyEventArgs e)
{
e.Handled = !IsNumberKey(e.Key) && !IsActionKey(e.Key) && !IsFormattingKey(e.Key) && !IsSpaceKey(e.Key);
}
protected override void OnLostFocus(object sender, RoutedEventArgs e)
{
bypassEvent = 1;
string content = Text;
char[] contents = content.ToCharArray();
if (content.Length == 10)
{
base.Text = Text.Substring(0, 3) + "-" + Text.Substring(3, 3) + "-" + Text.Substring(6, 4);
}
}
#endregion
}
}
答案 0 :(得分:1)
你可以这样实施一个标志:
private bool LosingFocus = false;
protected virtual void OnTextChanged(object sender, TextChangedEventArgs e)
{
if (LosingFocus != true)
{
base.Text = LeaveOnlyNumbers(Text);
}
LosingFocus = false;
}
protected override void OnLostFocus(object sender, RoutedEventArgs e)
{
LosingFocus = true;
string content = Text;
char[] contents = content.ToCharArray();
if (content.Length == 8)
{
base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + Text.Substring(4, 4);
}
else if (content.Length == 6)
{
int century = Convert.ToInt32(DateTime.Today.Year.ToString().Substring(2, 2));
string tempCentury = content[4].ToString() + content[5].ToString();
int unknownCentury = Convert.ToInt32(tempCentury);
if (unknownCentury > century + 1)
{
base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + "19" + Text.Substring(4, 2);
}
else base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + "20" + Text.Substring(4, 2);
}
else if (content.Length == 4)
{
base.Text = Text.Substring(0, 1) + "/" + Text.Substring(1, 1) + "/" + Text.Substring(2, 2);
int century = Convert.ToInt32(DateTime.Today.Year.ToString().Substring(2, 2));
string tempCentury = content[4].ToString() + content[5].ToString();
int unknownCentury = Convert.ToInt32(tempCentury);
if (unknownCentury > century + 1)
{
base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + "19" + Text.Substring(4, 2);
}
else base.Text = Text.Substring(0, 2) + "/" + Text.Substring(2, 2) + "/" + "20" + Text.Substring(4, 2);
}
}
只有在输入OnLostFocus时,默认设置为false的本地布尔变量才会设置为true。当选中输入OnTextChanged属性时,如果为true,则绕过逻辑并重置属性。