Last year I wrote a post on selecting text in a textbox control in two parts. You can find Part 1 here and Part 2 here. Another question came up in the news groups on selecting the text of a NumericUpDown control. Again sounds straight forward since the full .NET framework supports UpDownBase.Select. To get this functionality requires a little bit of work but is possible.
Basically to send a message to a control you have to PInvoke SendMessage in coredll.dll (user32.dll for the desktop). Here is the signature for that:
[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
To tell the control to select the text, the int msg parameter should be EM_SETSEL which is defined as follows:
private const int SETSEL = 0x00B1;
Now putting all together. Using Visual Studio 2005 we can create a class called NumericUpDownWithSelect and override the OnGotFocus method. Here is the implementation
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
if (!this.suppressOnGotFocus)
{
ThreadStart t = delegate()
{
this.Invoke(new SelectAllInvoke(SelectAll));
};
new Thread(t).Start();
}
You will notice we are using an anonymous method to invoke the SelectAll Method on the main thread. Here is the delegate signature and the implementation of SelectAll() and Select():
private delegate void SelectAllInvoke();
public void SelectAll()
{
this.SelectInternal(0, this.Value.ToString().Length);
}
public void Select(int start, int length)
{
this.SelectInternal(start, length);
}
SelectInternal()
is the code that does the actual work.
private void SelectInternal(int start, int length)
{
this.suppressOnGotFocus = true;
if (!this.Focused)
this.Focus();
IntPtr ret = SendMessage(this.Handle, SETSEL, start, length);
this.suppressOnGotFocus = false;
}
So putting it all together in a nice class that inherits from System.Windows.Forms.NumericUpDown you can extend the functionality of the base class. Here is the full implementation:
public class NumericUpDownWithSelect : NumericUpDown
{
public NumericUpDownWithSelect()
{
}
[DllImport("coredll.dll", SetLastError = true)]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);
private const int GETSEL = 0x00B0;
private const int SETSEL = 0x00B1;
private delegate void SelectAllInvoke();
private bool suppressOnGotFocus = false;
protected override void OnGotFocus(EventArgs e)
{
base.OnGotFocus(e);
if (!this.suppressOnGotFocus)
{
ThreadStart t = delegate()
{
this.Invoke(new SelectAllInvoke(SelectAll));
};
new Thread(t).Start();
}
}
public void SelectAll()
{
this.SelectInternal(0, this.Value.ToString().Length);
}
public void Select(int start, int length)
{
this.SelectInternal(start, length);
}
private void SelectInternal(int start, int length)
{
this.suppressOnGotFocus = true;
if (!this.Focused)
this.Focus();
IntPtr ret = SendMessage(this.Handle, SETSEL, start, length);
this.suppressOnGotFocus = false;
}
}
Download the binaries here:
NumericUpDownWithSelect_Binaries.zip (3.67 KB)