Customized Numeric Text Box Control in C# WinForms.

Peermohamedmydeen
Posted by Peermohamedmydeen under Windows Forms category on | Points: 40 | Views : 10994
Hello All,

While C# Winforms development, we cannot avoid writing an user control. because User controls are the customized controls which will give rich user interactiveness and will fulfill our business requirements.

For example we have to write a numeric text box, which will have the following features and limitations.

1. It has to allow 0-9, '-' , '.' characters.
2. it should not allow 2 Decimals characters.
3. it should not allow 2 minus.
4. It has to work with Ctrl+C, Ctrl+V, Ctrl+X options.
5. And we have to restrict the numeric text box with a limit.
6. It will have a precision limit.
7.It has to work with Numeric Keys in keyboard.


So here I have a simple Numeric text box, it is derived it from normal .NET TextBox control.

Please have a look at the following snippet.

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace MyApplication
{

public partial class NumericTextBox : TextBox
{

int WM_KEYDOWN = 0x0100, WM_PASTE = 0x0302;
int _precision = 4;
long _maxNumber = 32678;

public NumericTextBox()
{
InitializeComponent();

}



public NumericTextBox(IContainer container)
{
container.Add(this);
InitializeComponent();

}



public override bool PreProcessMessage(ref message msg)
{
string[] strNums = new string[2];
if(msg.Msg == WM_KEYDOWN)
{
Keys keys = (Keys)msg.WParam.ToInt32();
bool numbers = ((keys >= Keys.D0 && keys <= Keys.D9) || (keys >= Keys.NumPad0 && keys <= Keys.NumPad9)) && ModifierKeys != Keys.Shift;
bool ctrl = keys == keys.Control;
bool ctrolZ = keys == Keys.Z && ModifierKeys == Keys.Control,
ctrolX = keys == Keys.X && ModifierKeys == Keys.Control,
ctrolC = keys == Keys.C && ModifierKeys == Keys.Control,
ctrolV = keys == Keys.V && ModifierKeys == Keys.Control,
del = keys == Keys.Delete,
bksp = keys == Keys.Back,
home = keys == Keys.Home,
endKey = keys == Keys.End,
escape = keys == Keys.Escape,
enter = keys == Keys.Enter,
arrows = (keys == Keys.Up) | (keys == Keys.Down) | (keys == Keys.Left) | (keys == Keys.Right);

bool minus = ((keys == Keys.OemMinus || keys == Keys.Substract) && this.Text.Contains("-") == false);
bool dot = _precision > 0 & ((keys == Keys.OemPeriod || keys == Keys.Decimal) && this.Text.Contains(".") == false);
bool isTab = keys == Keys.Tab;
bool isShiftTab = keys == Keys.Tab && ModifierKeys == Keys.Shift;

strNums = this.text.Split('.');
bool isDotLimit = false;

if(strNums.getUpperBound(0) > 0)
{
if(strNums[1].Length >= _precision)
{
isDotLimit = true;
}
}

bool isNumLimit = false;
if(strNums[0].Length >= _maxNumber)
{
if(|isDotLimit && (this.Text.Contains(".") || dot || minus ))
{
isNumLimit = false ;
}
else
{
isNumLimit = true ;
}
}

if(isShiftTab == true)
{
msg.WParam = (IntPtr) ((int)Keys.Tab | (int)Keys.Shift);
rerturn base.PreProcessMessage(ref msg);
}

if(isTab == true)
{
msg.WParam = (IntPtr) ((int)Keys.Tab);
return.base.PreProcessMessage(ref msg);
}

if(escape == true)
{
msg.WParam = (IntPtr) ((int)Keys.Escape);
return.base.PreProcessMessage(ref msg);
}

else if(ctrl | del | bksp | arrows | ctrlC | ctrlX | ctrlZ | enter | home | endKey )
return false;

else if (isDotLimit == true)
return true;
else if (isNumLimit == true)
return true;

else if (numbers | dot)
return false;

else if (minus)
return false;

else if (escape)
{
return true;
}

else if (isTab == true)
{
this.AcceptTab = true;
return true;
}

if (ctrlV)
{

IDataObject obj = Clipboard.GetDataObject();
string input = (string)obj.GetData(typeof(string));
foreach(char c in input)
{
if(!char.IsDigit(c)) return true;
}

return false;

}

else
}
return true;
}
else
return base.PreProcessMessage(ref msg);
}



public int Precision
{
get { return _precision; }
set { _precision = value; }
}

public int MaxNumber
{
set
{

_maxNumber = value;
}

}


protected override void WndProc(ref Message m)
{
if(m.Msg == WM_PASTE)
{
IDataObject obj = Clipboard.GetDataObject();
string input = (string)obj.GetData(typeof(string));
foreach(char c in input)
{
if(!char.IsDigit(c))
{
m.Result = (IntPtr)0;
return;
}
}
}
base.WndProc(ref m);
}
}
}



Here we have overridden the PreProcessMsg of TextBox control. There we implemented all our business requirements.

And we have overridden WndProc to restrict the alphabetic characters while pasting into the control.


I think this code snippet will be helpful to you.



Thanks and Regards
PMM :)

Comments or Responses

Login to post response