单击文本框时,如何使其聚焦但不更改其内部的光标位置
本文关键字:内部 位置 光标 文本 聚焦 何使其 单击 | 更新日期: 2023-09-27 18:28:58
我为Textbox.Enter event
创建了一个事件处理程序,它选择文本框中的一部分文本,如下所示:TextBox1.Select(3,5);
结果如下:
当通过[Tab]或[Shift]-[Tab]通过键盘输入文本框时,
文本中需要选择的部分选择得很好,就像上面的屏幕截图一样。
但是,如果不是通过键盘而是通过鼠标输入文本框,
则不选择任何内容:
看起来发生的事情是这样的:
当我们用鼠标输入文本框时,
单击确实会引发Enter event
,但mouseclick也会将光标的位置设置为用户在文本框内用鼠标单击的位置
光标的此设置发生在事件处理程序运行之后。
因此,这意味着,事件处理程序执行的选择(使用TextBox1.Select(3,5);
行)将被鼠标的位置覆盖,
这就是为什么用鼠标输入文本框似乎没有选择任何内容。
我的问题:
如何使鼠标确实升高Enter event
,但不更改文本框内的光标位置
因此,我将能够保留我的选择(发生在代码中),而不会被覆盖。。
编辑:
这样做的目的是便于选择MM:SS时间部分,该部分通常是正在编辑的部分(HH或mmm部分很少更改)。
这是一个有点奇怪的请求,但如果你真的想这样做,你可以使用一种众所周知的通用方法,通过使用Control.BeginVoke方法来安排稍后执行的操作(在正常的windows消息/事件处理之后)。
像这样的
void textBox_Enter(object sender, EventArgs e)
{
BeginInvoke(new Action(() => textBox.Select(3, 5)));
}
更新:根据您的评论,如果您想防止默认的鼠标按下行为,您需要通过创建和使用您自己的TextBox
子类(如)来处理WM_MOUSEACTIVATE消息
class MyTextBox : TextBox
{
protected override void WndProc(ref Message m)
{
const int WM_LBUTTONDOWN = 0x0201;
const int WM_MOUSEACTIVATE = 0x0021;
const int MA_ACTIVATEANDEAT = 2;
const int MA_NOACTIVATEANDEAT = 4;
if (m.Msg == WM_MOUSEACTIVATE && !Focused)
{
int mouseMsg = unchecked((int)((uint)(int)m.LParam >> 16)); // LOWORD(m.LParam)
if (mouseMsg == WM_LBUTTONDOWN)
{
bool activated = Focus();
m.Result = (IntPtr)(activated ? MA_ACTIVATEANDEAT : MA_NOACTIVATEANDEAT);
return;
}
}
base.WndProc(ref m);
}
}
我想建议另一种方法:
在Control.Enter
事件处理程序的开头,我放置了以下内容:
while( (Control.MouseButtons&MouseButtons.Left)!=0 )
Application.DoEvents();
这只是等待释放鼠标左键。。
只有当鼠标左键释放时,我们才能继续下一行代码,即
TextBox1.Select(3,5);
然后它工作得很好——选择发生,而不会被覆盖。