我为Textbox.Enter event
创建了一个事件处理程序,它选择文本框中文本的一部分,如下所示:
TextBox1.Select(3,5);
结果如下:
通过键盘通过 [Tab] 或 [Shift] - [Tab] 输入文本框时,
选择需要选择的文本部分,就像上面的屏幕截图一样。
但是,如果不是通过键盘而是通过鼠标输入文本框,则 然后没有选择任何东西:
似乎会发生这样的事情:
当我们用鼠标进入文本框时,
点击确实会引发Enter event
,但鼠标点击还会将光标的位置设置为文本框内用户点击鼠标的位置。
在事件处理程序运行之后,光标的这个设置就会发生。
这意味着,事件处理程序执行的选择(使用TextBox1.Select(3,5);
行)被鼠标的位置覆盖,
这就是为什么用鼠标进入文本框,似乎没有选择任何东西。
如何让鼠标确实抬起Enter event
,而不是更改文本框内的光标位置?
因此,我将能够保留我的选择(在代码中发生)并且不会被覆盖..
编辑:
这样做的目的是为了能够轻松选择 MM:SS 部分时间,这通常是正在编辑的部分(HH或mmm部分很少更改)。
答案 0 :(得分:2)
有点奇怪的请求,但是如果你真的想这样做,你可以使用一个众所周知的通用方法来安排稍后执行的操作(在正常的Windows消息/事件处理之后)使用Control.BeginInvoke方法
像这样的东西
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);
}
}
答案 1 :(得分:1)
我想建议另一种方式:
在Control.Enter
事件处理程序的开头,我把它放在:
while( (Control.MouseButtons&MouseButtons.Left)!=0 )
Application.DoEvents();
这只是等待鼠标左键被释放..
只有释放鼠标左键时,我们才会继续下一行代码,即
TextBox1.Select(3,5);
然后它运作良好 - 选择发生,而不被覆盖。