I created an event handler for the Textbox.Enter event
, which selects a part of the text inside the textbox, like this:TextBox1.Select(3,5);
The result looks like this:
When the Textbox is entered via the Keyboard via [Tab] or [Shift]-[Tab],
the part of the text that needs to be selected is selected well, just like in the screenshot above.
However if the textbox is entered not via the keyboard but via the mouse,
then nothing is selected:
It seems that what happens is this:
When we enter the textbox with the mouse,
the click indeed raises the Enter event
, but the mouseclick also sets the location of the cursor, to the location the user clicked with the mouse, inside the textbox.
And this setting of the cursor happens right after the event handler was ran.
So this means, that the selection that the event handler performed (with the TextBox1.Select(3,5);
line), is overridden by the mouse's location,
and that's why entering the textbox with the mouse, appears to not select anything.
How can I make the mouse indeed raise the Enter event
, yet not change the cursor position inside the textbox?
So I will then be able to have my selection (that happens in code) remain and not be overridden..
Edit:
The purpose of this is to enable easy selection of the MM:SS part of the time, which is usually the part that is being edited (the HH or mmm parts are rarely changed).
A bit strange request, but if you really want to do so, you can use a well known general method for scheduling an action to be executed later (after normal windows message/event processing) by using the Control.BeginInvoke method.
Something like this
void textBox_Enter(object sender, EventArgs e)
{
BeginInvoke(new Action(() => textBox.Select(3, 5)));
}
Update: As per your comment, if you want to prevent the default mouse down behavior, you need to handle the WM_MOUSEACTIVATE message by creating and using your own TextBox
subclass like this
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);
}
}
I would like to suggest another way:
In the beginning of the Control.Enter
event handler, I put this:
while( (Control.MouseButtons&MouseButtons.Left)!=0 )
Application.DoEvents();
This simply waits for the mouse Left button to be released..
Only when the mouse Left button is released, then we continue to the next line of code, which is
TextBox1.Select(3,5);
and it then works well - the selection happens, without being overridden.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With