http://www.codeproject.com/Articles/4693/IP-Address-TextBox
可以下载试用效果。个人感觉功能很强大,但输入时让人不太舒服。可以参考。
ntroduction
Problem was, I didn't find a solution to edit an IP address like in Windows network environment, for C#. Although there are some controls for masked edit fields, I wanted to write my own, and if so I wanted it to behave like the controls from MFC library or Windows network environment and maybe a little more.
Problems to solve
The heaviest problem at writing the control was to catch the inputs of backspace and delete keys, to delete characters from the input field. I tried a lot with overridden event handlers, OnKeyDown
and OnKeyUp
but it didn't work like it should.
Then I remembered that another developer had overridden the PreProsessMessage
method to catch keyboard inputs and handle it in own ways. So I implemented an override for PreProcessMessage
to handle all the backspaces and delete key presses and used OnKeyUp
, OnKeyPress
and OnKeyDown
to handle the inputs of dots and slashes and set the input cursor to the right position.
OnKeyDown event
/// <summary>
/// Override standard KeyDownEventHandler
/// Catches Inputs of "." and "/" to jump to next positions
/// </summary>
/// <param name="e">KeyEventArgument</param> protected override void OnKeyDown(KeyEventArgs e)
{
//Zeichen an die richtige stelle schreiben
int iPos = this.SelectionStart;
char[] cText = this.Text.ToCharArray();
if(e.Modifiers == Keys.None)
{
if((char.IsLetterOrDigit(Convert.ToChar(e.KeyValue)) ||
e.KeyCode == Keys.NumPad0)//Numpad0=96 --> `
&& iPos < this.TextLength)
{
if(cText[iPos] == '.' || cText[iPos] == ':'
|| cText[iPos] == '/')
iPos+=;
this.SelectionStart = iPos;
if(this.OverWriteMode)
{
if(cText[iPos] != ' ')
this.SelectionLength = ;
}
else
{
if(iPos < this.TextLength)
if(cText[iPos] == ' ')
this.SelectionLength = ;
}
}
}
base.OnKeyDown (e);
}
OnKeyUp event
/// <summary>
/// Override standard KeyUpEventHandler
/// Catches Inputs of "." and "/" to jump to next positions
/// </summary>
/// <param name="e">KeyEventArgument</param> protected override void OnKeyUp(KeyEventArgs e)
{
//Zeichen an die richtige stelle schreiben
int iPos = this.SelectionStart;
char[] cText = this.Text.ToCharArray(); //Cursor hintern Punkt setzen
if((char.IsLetterOrDigit(Convert.ToChar(e.KeyValue)) ||
e.KeyCode == Keys.NumPad0)//Numpad0=96 --> `
&& iPos < this.TextLength)
{
if(cText[iPos] == '.' || cText[iPos] == ':'
|| cText[iPos] == '/')
iPos+=;
this.SelectionStart = iPos;
}
base.OnKeyUp (e);
}
OnKeyPress event
/// <summary>
/// Override standard KeyPressEventHandler
/// Catches Inputs of "." and "/" to jump to next positions
/// </summary>
/// <param name="e">KeyPressEventArgument</param> protected override void OnKeyPress(KeyPressEventArgs e)
{
//Zulassige Zeichen
if(char.IsControl(e.KeyChar) ||
m_regexValidNumbers.IsMatch(e.KeyChar.ToString()))
{
e.Handled = false;
}
else
{
switch(e.KeyChar)
{
case '/':
this.JumpToSlash();
break;
case '.':
this.JumpToNextDot();
break;
default:
break;
}
e.Handled = true;
}
base.OnKeyPress(e);
}
PreProcessMessage
/// <summary>
/// Override standard PreProcessMessage
/// Catches Inputs of BackSpace and Deletes
/// </summary>
/// <param name="msg">PreProcessMessage</param> public override bool PreProcessMessage(ref Message msg)
{
if (msg.Msg == WM_KEYDOWN)
{
Keys keyData = ((Keys) (int) msg.WParam) |ModifierKeys;
Keys keyCode = ((Keys) (int) msg.WParam); int iPos = this.SelectionStart;
char[] cText = this.Text.ToCharArray();
switch(keyCode)
{
case Keys.Delete:
if(iPos < this.TextLength)
{
while(cText[iPos] == '.' ||
cText[iPos] == ':' ||
cText[iPos] == '/')
{
if((iPos+=) >= cText.Length)
break;
}
if(iPos < this.TextLength)
{
base.Text = this.Text.Substring(,iPos) +
" " + this.Text.Substring(iPos+);
this.SelectionStart = iPos+;
}
else
this.SelectionStart = this.TextLength-;
}
return true;
case Keys.Back:
if(iPos > )
{
while(cText[iPos-] == '.' ||
cText[iPos-] == ':' ||
cText[iPos-] == '/')
{
if((iPos-=)<=)
break;
}
if(iPos>)
{
base.Text = this.Text.Substring(,iPos-)
+ " " + this.Text.Substring(iPos);
this.SelectionStart = iPos-;
}
else
this.SelectionStart = ;
}
return true;
default:
break;
}
}
return base.PreProcessMessage (ref msg);
}
Another problem was the input of numbers via the numpad. Especially the 0 key was not recognized, because it's char value is neither a letter nor a digit, so I had to ask for Keys.NumPad0
hard coded.
if((char.IsLetterOrDigit(Convert.ToChar(e.KeyValue)) ||
e.KeyCode == Keys.NumPad0)//Numpad0=96 --> `
iPos < this.TextLength)
{[...]}
At least...
...I have a control that looks like a TextBox
with dots, where I can input numbers, type dots to jump to next IP parts, and get its contents via the Text
property.
Using the code
Include the IPAddressTextBox.cs in your project. Set a TextBox
in your form or user control and clear its contents. Change the type of this TextBox
from System.Windows.Forms.TextBox
to rj2_cs.IPAddressTextBox
in code editor. Then you can change the properties of the IP textbox like you want.