我希望能够覆盖将插入符号定位在蒙面文本框中的默认行为。
默认设置是将插入符号放置在单击鼠标的位置,由于掩码,被掩码的文本框已经包含字符。
我知道你可以像这篇文章中提到的那样隐藏插入符号,当控件获得焦点时,是否有类似的东西可以将插入符号定位在文本框的开头。
我希望能够覆盖将插入符号定位在蒙面文本框中的默认行为。
默认设置是将插入符号放置在单击鼠标的位置,由于掩码,被掩码的文本框已经包含字符。
我知道你可以像这篇文章中提到的那样隐藏插入符号,当控件获得焦点时,是否有类似的东西可以将插入符号定位在文本框的开头。
这应该可以解决问题:
private void maskedTextBox1_Enter(object sender, EventArgs e)
{
this.BeginInvoke((MethodInvoker)delegate()
{
maskedTextBox1.Select(0, 0);
});
}
为了改进阿巴斯的工作解决方案,试试这个:
private void ueTxtAny_Enter(object sender, EventArgs e)
{
//This method will prevent the cursor from being positioned in the middle
//of a textbox when the user clicks in it.
MaskedTextBox textBox = sender as MaskedTextBox;
if (textBox != null)
{
this.BeginInvoke((MethodInvoker)delegate()
{
int pos = textBox.SelectionStart;
if (pos > textBox.Text.Length)
pos = textBox.Text.Length;
textBox.Select(pos, 0);
});
}
}
此事件处理程序可以与多个框重复使用,并且它不会剥夺用户将光标定位在输入数据中间的能力(即当框不为空时不会强制光标进入第零位)。
我发现这更接近于模仿标准文本框。剩下的唯一故障(我可以看到)是在“Enter”事件之后,如果 xe 按住鼠标并拖动到末尾,用户仍然能够选择(空)掩码提示的其余部分。
这是对 MaskedTextBoxes 的默认行为的一大改进。谢谢!
我对 Ishmaeel 的出色解决方案进行了一些更改。我更喜欢仅在需要移动光标时才调用 BeginInvoke。我还从各种事件处理程序中调用该方法,因此输入参数是活动的 MaskedTextBox。
private void maskedTextBoxGPS_Click( object sender, EventArgs e )
{
PositionCursorInMaskedTextBox( maskedTextBoxGPS );
}
private void PositionCursorInMaskedTextBox( MaskedTextBox mtb )
{
if (mtb == null) return;
int pos = mtb.SelectionStart;
if (pos > mtb.Text.Length)
this.BeginInvoke( (MethodInvoker)delegate() { mtb.Select( mtb.Text.Length, 0 ); });
}
部分答案:您可以通过在 MouseClick 事件中为控件分配 0 长度选择来定位插入符号,例如:
MaskedTextBox1.Select(5, 0)
...将插入符号设置在文本框中的第 5 个字符位置。
这个答案只是部分的原因,是因为我想不出一种普遍可靠的方法来确定插入符号应该在点击时定位的位置。这对于某些掩码可能是可能的,但在某些常见情况下(例如美国电话号码掩码),我真的想不出一种简单的方法来将掩码和提示字符与实际用户输入分开......
//not the prettiest, but it gets to the first non-masked area when a user mounse-clicks into the control
private void txtAccount_MouseUp(object sender, MouseEventArgs e)
{
if (txtAccount.SelectionStart > txtAccount.Text.Length)
txtAccount.Select(txtAccount.Text.Length, 0);
}
这个解决方案对我有用。请试一试。
private void maskedTextBox1_Click(object sender, EventArgs e)
{
maskedTextBox1.Select(maskedTextBox1.Text.Length, 0);
}
我使用 Click 事件让我的工作......不需要 Invoke。
private void maskedTextBox1_Click(object sender, EventArgs e)
{
maskedTextBox1.Select(0, 0);
}
该解决方案使用了像 Gman Cornflake 一样的 MaskedTextBox 的 Click 方法;但是,我发现有必要允许用户在 MaskedTextBox 内单击,一旦它包含数据并且光标停留在它所在的位置。
下面的示例关闭提示和文字,并评估 MaskedTextBox 中数据的长度,如果等于 0,则将光标置于起始位置;否则它只是绕过将光标放在起始位置的代码。
代码是用 VB.NET 2017 编写的。希望对您有所帮助!
Private Sub MaskedTextBox1_Click(sender As Object, e As EventArgs) Handles MaskedTextBox1.Click
Me.MaskedTextBox1.TextMaskFormat = MaskFormat.ExcludePromptAndLiterals
If Me.MaskedTextBox1.Text.Length = 0 Then
MaskedTextBox1.Select(0, 0)
End If
Me.MaskedTextBox1.TextMaskFormat = MaskFormat.IncludePromptAndLiterals
End Sub
我知道这是一个老问题,但谷歌已经多次将我带到这里,但没有一个答案完全符合我的要求。
例如,当您使用TextMaskFormat = MaskFormat.ExcludePromptAndLiterals
.
下面的方法使输入文本框时光标跳转到第一个提示。输入文本框后,您可以自由移动光标。它也适用于MaskFormat.ExcludePromptAndLiterals
.
这就是为什么我认为值得把它留在这里:)
private void MaskedTextBox_Enter(object sender, EventArgs e)
{
// If attached to a MaskedTextBox' Enter-Event, this method will
// make the cursor jump to the first prompt when the textbox gets focus.
if (sender is MaskedTextBox textBox)
{
MaskFormat oldFormat = textBox.TextMaskFormat;
textBox.TextMaskFormat = MaskFormat.IncludePromptAndLiterals;
string fullText = textBox.Text;
textBox.TextMaskFormat = oldFormat;
int index = fullText.IndexOf(textBox.PromptChar);
if (index > -1)
{
BeginInvoke(new Action(() => textBox.Select(index, 0)));
}
}
}