IP-Address TextBox

http://www.codeproject.com/KB/edit/IPAddressTextBox.aspx
Search    
Advanced Search
Sitemap
16 votes for this Article.
Popularity: 4.00 Rating: 3.32 out of 5
2 votes, 12.5%
1
2 votes, 12.5%
2
3 votes, 18.8%
3
5 votes, 31.3%
4
4 votes, 25.0%
5

Introduction

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+=1;
this.SelectionStart = iPos;
if(this.OverWriteMode)
{
if(cText[iPos] != ' ')
this.SelectionLength = 1;
}
else
{
if(iPos < this.TextLength)
if(cText[iPos] == ' ')
this.SelectionLength = 1;
}
}
}
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+=1;
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+=1) >= cText.Length)
break;
}
if(iPos < this.TextLength)
{
base.Text = this.Text.Substring(0,iPos) +
" " + this.Text.Substring(iPos+1);
this.SelectionStart = iPos+1;
}
else
this.SelectionStart = this.TextLength-1;
}
return true;
case Keys.Back:
if(iPos > 0)
{
while(cText[iPos-1] == '.' ||
cText[iPos-1] == ':' ||
cText[iPos-1] == '/')
{
if((iPos-=1)<=0)
break;
}
if(iPos>0)
{
base.Text = this.Text.Substring(0,iPos-1)
+ " " + this.Text.Substring(iPos);
this.SelectionStart = iPos-1;
}
else
this.SelectionStart = 0;
}
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.

Changes/Modifications

  • 2003-08-05
    • Implemented some exception handling at IP-Validation
    • Compiled in an assembly it can be used via Visual Studio Designer
    • Text property overridden, so you can only enter valid IP addresses
    public override string Text
    {
    get
    {
    return base.Text;
    }
    set
    {
    try
    {
    if(IPAddressTextBox.ValidateIP(value,
    this.m_newIPNotation, this.m_arlDelimeter))
    base.Text = IPAddressTextBox.MakeValidSpaces(value,
    this.m_newIPNotation, this.m_arlDelimeter);
    }
    catch
    { }
    }
    }
  • 2003-08-06
    • Bug fix: Invalid IP addresses could not be changed by deleting characters, because of the validation of the Text property --workaround-> Delete/Backspaces change the base.Text property
    • Additional Method: GetPureIPAddress(), returns the IP address in the Text field without leading zeroes or leading/trailing spaces
    public string GetPureIPAddress()
    {
    string s = "";
    ArrayList arlIP = new ArrayList(this.Text.Replace(" ","").
    Split((char[])this.m_arlDelimeter.ToArray(typeof(char))));
    for(int i=0; i <arlIP.Count; i++)
    {
    while(arlIP[i].ToString().StartsWith("0"))
    arlIP[i] = arlIP[i].ToString().Substring(1);
    }
    s = IPAddressTextBox.MakeIP(
    (string[])arlIP.ToArray(typeof(string)),
    this.m_ipNotation);
    /*in IPv6 Addresses replace 0000: by ::*/
    if(this.m_ipNotation == IPNotation.IPv6Hexadecimal ||
    this.m_ipNotation == IPNotation.IPv6HexadecimalCIDR ||
    this.m_ipNotation == IPNotation.IPv6Binary ||
    this.m_ipNotation == IPNotation.IPv6BinaryCIDR)
    {
    while(s.IndexOf(":::")>=0)
    {
    s = s.Remove(s.IndexOf(":::"),1);
    }
    }
    return s;
    }
  • 2003-08-11
    • Hide unneeded members from base class in Studio Designer
    • IPv6 implemented properly (I hope)
    • Properties, events and event handlers for "Binary", "IPv6", "Subnet" deleted
    • Notation-Property,-Event and -event handler added: Value is one of the IPNotation enumeration
      public enum IPNotation
      {
      IPv4Decimal,
      /*192.168.000.001*/
      IPv4Binary,
      /*11000000.10101000.00000000.00000001*/
      IPv4DecimalCIDR,
      /*192.168.000.001/16*/
      IPv4BinaryCIDR,
      /*11000000.10101000.00000000.00000001/16*/
      IPv6Hexadecimal,
      /*0000:0000:0000:0000:00c0:00a8:0000:0001*/
      IPv6Binary,
      /*0000000000000000:0000000000000000:
      0000000000000000:0000000000000000:
      0000000011000000:0000000010101000:
      0000000000000000:0000000000000001*/

      IPv6HexadecimalCIDR,
      /*0000:0000:0000:0000:00c0:00a8:0000:0001/16*/
      IPv6BinaryCIDR,
      /*0000000000000000:0000000000000000:
      0000000000000000:0000000000000000:
      0000000011000000:0000000010101000:
      0000000000000000:0000000000000001/16*/

      IPv6IPv4Decimal,
      /*::192.168.000.001*/
      IPv6IPv4Binary,
      /*::11000000.10101000.00000000.00000001*/
      IPv6IPv4DecimalCIDR,
      /*::192.168.000.001/16*/
      IPv6IPv4BinaryCIDR
      /*::11000000.10101000.00000000.00000001/16*/
      }
    • Change of the Notation Property causes call of a huge function that converts the given IP-Address to the new Notation
    • Default value of property OverWriteMode changed to true
    • Some changes in demo project to test the new properties and functions
  • 2003-09-01
    • Default value for property OverWriteMode set to true (else the VS-Designer couldn't change the property the code)
    • IPv4 addresses now have zeroes between dots (previously forgotten in MakeIP/GetPureIP methods)
    • Copy and paste via keyboard inputs enabled; check if modifier-key is pressed in OnKeyDown override (can just copy/paste whole IP addresses or part between dots, all the others I still have to implement)
    protected override void OnKeyDown(KeyEventArgs e)
    {
    int iPos = this.SelectionStart;
    char[] cText = this.Text.ToCharArray();
    if(e.Modifiers == Keys.None)
    {
    //[some code]

    }
    base.OnKeyDown (e);
    }

    Demo packet changed, so you don't have to download source packet.

TODO

  • Move digits to right, if there is an input and there are spaces left to next delimiter
  • Accept optimized IPv6 addresses (with :: instead of 0000: ) for set_Text property
  • Enable drag/drop

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

RJ2


- Attended School from 1985-1998
- began programming in QBasic and Turbo-Pascal
- tried something with HTML, Perl, PHP
- Apprenticeship from 1999-2002 as Software Developer
- learned write programs with high level languages like C, C++, since 2002 C#
- wrote a lot of GUI applications
- since 2002 working as software developer for GUI Applications and Installation-Packages at Ferrari electronic AG (Germany, Teltow)
- continuing programming with high level languages to develop GUIs and helper libraries for installation packages
Occupation: Web Developer
Location: Germany Germany

Other popular Edit Controls articles:

src="http://www.codeproject.com/script/Adm/ServeHTML.aspx?C=False&adid=7562" scrolling="no" width="300" frameborder="0" height="250">
<script type="text/javascript" language="JavaScript"> var socialLinks = new social(); socialLinks.addtoMethod=1; socialLinks.DrawLinks("socialLinks", document.location.href, escape(document.title), 100, 0, "SmallText Bold", "AddTo"); </script>
Article Top
Sign Up to vote for this article
src="http://www.codeproject.com/script/Adm/ServeHTML.aspx?C=False&adid=7585" scrolling="no" width="468" frameborder="0" height="60"> src="http://www.codeproject.com/script/Adm/ServeLinks.aspx?C=False&ids=5229,5234,6456" scrolling="no" width="300" frameborder="0" height="60">
 Msgs 1 to 17 of 17 (Total in Forum: 17) (Refresh)First</span><span class="Frm_HL">Prev</span><span class="Frm_HL">Next
Subject  Author Date 
Generalquestionmemberfradev6:48 13 Oct '06  

Cool, but is there a way to say if the box is filled or not.
Some checks like for example (IsFilled-> true if the box was filled with a valid IP Address) )

Thanks
GeneralZipssussAnonymous2:03 12 Oct '05  

I don't know if this is what the mysterious messages on the board about source code are about, but as far as I have been able to download them, the zip files appear to be corrupt Cry.

Any chance you can check this?
AnswerRe: ZipsmemberRJ22:36 12 Oct '05  

I tried it myself (Oct 12 2005, 13:35 CET) and everything was alright.

I'd try to download from another article. If that doesn't work, too, something is wrong with your login on codeproject or similar.

regards
RJ2
GeneralpreventLeaveOnErrormemberMustafa Özden20:20 11 May '05  

Hello,

Thanks for sharing this useful code.

One problem I ran into is about leaving the textbox when error present. I get an exception from validateIp() including the error (e.g. IP element 2 is invalid(999) ). PreventLeaveOnError is "true". This means (I suppose) preventLeaveOnError does not function correctly. Any ideas?

A quickfix i tried was writing a "leave" method for textbox that can get error status from errorprovider and function accordingly (prevent leave function actually ) but as a c#&.Net newbie, i could not fetch the error status. Is there a way to understand if invalid IP error is present or not at a moment ?


Mustafa
GeneralRe: preventLeaveOnErrormemberRJ223:26 18 May '05  

Hello Mustafa,

the Property "PreventLeaveAtError" says it prevents the leave of the control if there is an input error.

If you set the property to "false" you should be able to leave the control even if there is an input error.

To see what error was thrown by "ValidateIP" watch the debug output window.

Hope i could help you
RJ2
GeneralRe: preventLeaveOnErrormemberMustafa ÖZDEN21:49 22 May '05  

Hello RJ2,

The aim of "preventLeaveOnError" property is quite obvious. Thanks anyway.

You can try to put a normal textbox and an IPAddressTextbox together on a form and write a wrong IP, say (333.333.333.333). And of course PreventLeaveOnError = true . While ErrorProvider is blinking, leave to edit the other normal textbox. This was where I got the exception, and application exit. (I only use IPv4 validation.)

I solved the problem by try-catching inside the ValidateIP() method. Also, I override the OnLeave event of base textbox, preventing leave if preventLeaveOnError = true and error is present.. I could not go deeper into the code to find a more proper solution, just quickfixed the problem. I suppose an exception is thrown somewhere in validateIp() methods and not caught.

Thanks again for sharing this useful code.

Mustafa ÖZDEN
Generalthank you very muchmemberranjithlogics23:55 10 May '05  

the validator helped me very much. thanx a lotSmile

ranjith
GeneralRe: I can't use the source codememberRJ25:16 30 Sep '04  

So, waht do you think i'll do with such a message?

Would you please specify your Problem?
As you can see there were no changes in his project since a lot of months and i actually don't know what i did or what you did.

BiBa
GeneralnicememberTaha Zayed16:35 24 Sep '04  

Wink
GeneralException in the designermemberAnthony_Yio19:54 4 Mar '04  

My VS.NET form designer complain about exception when i try to view it in the form designer.

Below is the exception message.

Exception from HRESULT: 0x80131019

I am using VS.NET 7.0.9466



Sonork 100.41263:Anthony_Yio
GeneralSource?sussAnonymous3:11 23 Aug '03  

mmmm.... I can't find all source files in the "Download demo project - 25 Kb" download. It looks like there are missing a huge 73Kb source fine in there?

GeneralRe: Source?memberRJ222:47 24 Aug '03  

If there are not any source files, you do not need it. to run the demo project in source you have to download the Source-Code files and and them to the demoproject.
I will change the demo project download in future editions to solve these problems.

Bye
GeneralDemo not workingmemberSébastien Lorion21:02 16 Aug '03  

I downloaded demo and it's not working, it is missing some source files ...

Also, I didn't try it but make sure you validate drag/drop and copy/paste ...



Intelligence shared is intelligence squared.

Homepage : http://www.slorion.webhop.org
GeneralRe: Demo not workingmemberRJ210:16 17 Aug '03  

Sébastien, thank you for your reply

i'll keep a look at copy'n'paste (and drag'n'drop)

to run the Demo project try it in a different way.
Download the demo and the source-code. Add the source code files to the studio project, instead of the missing assembly and press run.

or try to run the compiled version from the release directory of demoproject

bye Ralf
GeneralRe: Looks useful, but...sussAnonymous16:09 20 Aug '04  

yes... usefull... unlike your post... stfu WTF
GeneralGood start but...memberCarl Mercier7:40 4 Aug '03  

I have been able to make it crash in about 20 seconds!

Very promising though!

GeneralRe: Good start but...memberRJ221:11 4 Aug '03  

it would be very usefull if you tell me, how you did it, so i can fix it
(or how you fixed it)

bye RJ2

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 31 Aug 2003
Editor: Smitha Vijayan
Copyright 2003 by RJ2
Everything else Copyright © CodeProject, 1999-2008
Web15 | Advertise on the Code Project

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.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值