2017-02-27 48 views
0

我有一个TextBox其中一个用户是为了输入产品代码,看起来像这样:文本框为产品代码 - 处理破折号

XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

我试图做的是自动放置在用户输入时在正确的位置破折号,以便他们只需输入实际的代码本身(类似于各种软件中所做的)。

我遇到的问题与用户输入时光标的位置有关。

我目前的解决方案(部分工作)是以下几点:

private void textBoxProductKey_KeyPress(object sender, KeyPressEventArgs e) 
{ 
    if (char.IsControl(e.KeyChar)) 
    { 
     return; 
    } 

    if (!char.IsLetterOrDigit(e.KeyChar) || textBoxProductKey.Text.Length == 29) 
    { 
     e.Handled = true; 
     return; 
    } 

    var cursorPosition = textBoxProductKey.SelectionStart; 
    string text; 

    if (cursorPosition == 0) 
    { 
     text = e.KeyChar + textBoxProductKey.Text; 
    } 
    else if (cursorPosition == textBoxProductKey.Text.Length) 
    { 
     text = textBoxProductKey.Text + e.KeyChar; 
    } 
    else 
    { 
     text = textBoxProductKey.Text.Insert(cursorPosition, e.KeyChar.ToString()); 
    } 

    text = Regex.Replace(text, "-", ""); 
    text = Regex.Replace(text, ".{5}", "$0-"); 
    textBoxProductKey.Text = text.Length <= 29 ? text : text.Substring(0, 29); 

    textBoxProductKey.SelectionStart = cursorPosition/6 == (cursorPosition + 1)/6 
     ? cursorPosition + 1 
     : cursorPosition + 2; 

    e.Handled = true; 
} 

两个问题,我目前的解决方案是

  • 它不能正确处理删除/退格键,其中可能破折号需要删除/插入不同的位置并重新计算光标位置
  • 如果cursorPosition == textBoxProductKey.Text.Length不能正常工作。

后者很容易修复,但我正在努力与前者,也觉得代码有点复杂。

我该如何更轻松地达到此目的(请注意计划将继续使用TextBox对象)。

编辑

我知道了MaskedTextBox控制的,我不希望使用MaskedTextBox,我想用一个TextBox

我想要做的事情并不在TextBox的可能性范围之外,即使有其他控件可以实现这种“更简单”的方法。

此外,我觉得这是一个很好的问题,教人们如何使用光标TextBox(其中可能)。

+4

的'MaskedTextBox'可能是你在找什么►[https://msdn.microsoft.com/en-us/library/system.windows .forms.maskedtextbox(v = vs.110).aspx](https://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox(v = vs.110).aspx) - In “注意计划是继续使用TextBox对象” - 我只能说,使用正确的工具来完成正确的工作,否则您的自定义代码可能会最终尝试解决特定情况下的特定问题。 ,方形挂钩,圆孔等。 – Nope

+2

'我知道MaskedTextBox控件,我不想使用MaskedTextBox,我想使用TextBox.' - 当然它可能并且有很多SO帖子已经显示你如何在文本框上实现你自己的掩码,但它们都会遇到问题,因此,使用MaskedtextBox。 '我也觉得这是教人们如何在TextBox中使用光标的一个很好的问题 - 我不确定是否通过教导如何不使用正确的工具来完成正确的工作并过度复杂化简单的解决方案是关于恕我直言的正确方法。 – Nope

+0

您是否尝试保存之前的文本值?这样,每次更改后,您都可以通过长度和值进行比较 - 如果用户粘贴文本,也可以使用。 –

回答

2

您是否考虑过使用MaskedTextBox控件?这可能更合适。

MaskedTextBox的设计正是为了这种类型的需求,并会回答你原来的问题。

您可能会发现使用普通文本框自己实现此功能更加困难。衡量哪种解决方案更可能无缺陷且更容易维护也是值得的。

如果您能向我们解释为什么您更喜欢在MaskedTextBox上使用文本框,可能会有所帮助。

+1

我有,并决定反对它(正如我的问题中提到的计划是继续使用'TextBox'对象)。此外,我不这样做会是你放在*评论*中,而不是答案,因为它根本不回答这个问题。 – cogumel0

+0

尽管进行了编辑,但这仍然不是答案,并且在评论部分(此属于哪个部分)中讨论过我不愿意使用“MaskedTextBox”的问题。 – cogumel0

0

继续我们的谈话,保存您当前的脱字符位置,将全文解析为新的,并将脱字符号还原到其原始位置。

这样,你处理删除以及复制粘贴

+0

将插入符号还原到原始位置并不总是理想的效果。想象一下这种情况:用户输入产品密钥,他得到5个字符,例如,他输入'12345'。此时字符串的长度是5,插入符号位于5。现在,因为每5个字符应该自动添加一个短划线,所以现在添加了一个短划线,所以字符串是'12345-',并根据你说,脱字符号放回原来的位置。现在,插入符号将在破折号之前,当它应该在破折号之后。 – cogumel0

+0

你建议类似'TextChanged',而不是'KeyPress'。但是这不起作用,你需要知道删除或退格键是否被按下。场景:用户在“5”和连字符之间插入“12345-6”。如果他们按删除,文字应该是'12345',脱字符号在5之后(脱字符不移动)。但是,如果插入符号位于连字符和6之间,并且按下退格键,则文本应该是'12346',插入符号位于4和6之间(插入符号向后移动一个位置)。知道删除或退格是否被按下是至关重要的! – cogumel0