学习,不断的学习

欢迎大家提供宝贵经验
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

IP输入框,第一次写windows控件,请各位多指点

Posted on 2005-08-23 15:00  sholden  阅读(1218)  评论(0编辑  收藏  举报
设计思路是将一个Panel中定位4个TextBox,然后在每个输入框中间画上点。另外还要考虑的就是对不同键盘按键的响应。
下面是IP输入框主对象:
  1using System;
  2using System.Collections;
  3using System.ComponentModel;
  4using System.Drawing;
  5using System.Data;
  6using System.Windows.Forms;
  7
  8namespace WindowsControlLibrary
  9{
 10    /// <summary>
 11    /// IPTextBox 的摘要说明。
 12    /// </summary>

 13    [DefaultProperty("IPV"),DefaultEvent("Resize")]
 14    public class IPTextBox : System.Windows.Forms.Panel
 15    {
 16        /// <summary>
 17        /// 必需的设计器变量。
 18        /// </summary>

 19        private System.ComponentModel.Container components = null;
 20        private int sectLen ;
 21        private int sectHeight;
 22        private int minLen;
 23        private IPVersion ipv = IPVersion.IPV4;
 24        private IPSection[] IPArray ;
 25        private IPSection currentFocused;
 26
 27        private const int firstMin = 1;
 28        private const int firstMax = 223;
 29        private const int otherMin = 0;
 30        private const int otherMax = 255;
 31
 32        public enum IPVersion{IPV4=4,IPV6=8};
 33
 34        public IPTextBox()
 35        {
 36            // 该调用是 Windows.Forms 窗体设计器所必需的。
 37            InitializeComponent();
 38            // TODO: 在 InitComponent 调用后添加任何初始化
 39            InitStyle();
 40            InitControl();
 41            
 42        }

 43
 44        /// <summary>
 45        /// 初始化控件样式
 46        /// </summary>

 47        private void InitStyle()
 48        {
 49            this.BackColor = Color.White;
 50            this.BorderStyle = BorderStyle.Fixed3D;
 51            this.Height = 23;
 52            this.Width = 100;
 53            this.minLen = 30+ (IPSection.GetWidth()+1)*(int)ipv;
 54            if (minLen > this.Width)
 55            {
 56                this.Width = minLen;
 57            }

 58            this.Resize +=new EventHandler(IPTextBox_Resize);
 59        }

 60
 61        /// <summary>
 62        /// 初始化子控件
 63        /// </summary>

 64        private void InitControl()
 65        {
 66            this.SuspendLayout();
 67            this.Controls.Clear();
 68
 69            this.sectHeight = IPSection.GetHeight();
 70            this.sectLen = (this.Width-10)/(int)ipv;
 71
 72            //paint input textbox
 73            this.IPArray = new IPSection[(int)ipv];
 74            Point point ;
 75            IPSection section;
 76            int index = 5;
 77            for (int i=0;i<(int)ipv;i++)
 78            {
 79                section = new IPSection();
 80                section.Name = "section_"+(i+1);
 81                IPArray[i] = section;
 82                point = new Point((this.sectLen-section.Width)/2+index,(this.Height-section.Height)/2);
 83                section.Location = point;
 84                this.Controls.Add(section);
 85                index += this.sectLen;
 86            }

 87            this.ResumeLayout(false);
 88        }

 89
 90        /// <summary>
 91        /// 设置IP版本,IPV4和IPV6,目前还没有处理IPV6的情况
 92        /// </summary>

 93        [Category("设计"),
 94        Editor(typeof(IPVersion),typeof(Enum)),
 95        Browsable(true)]
 96        public IPVersion IPV
 97        {
 98            get
 99            {
100                return ipv;
101            }

102            set
103            {
104                this.ipv = value;
105            }

106        }

107
108        /// <summary>
109        /// 当前焦点所在的输入框
110        /// </summary>

111        internal IPSection CurrentFocus
112        {
113            get
114            {
115                return currentFocused;
116            }

117            set
118            {
119                currentFocused = value;
120            }

121        }

122
123        /// <summary>
124        /// 获取IP字串
125        /// </summary>

126        public string IPAddress
127        {
128            get
129            {
130                CompleteIPAddress();
131                string ip = "";
132                for (int i=0;i<IPArray.Length;i++)
133                {
134                    ip += IPArray[i].Text+".";
135                }

136                ip = ip.Substring(0,ip.Length-1);
137                return ip;
138            }

139        }

140
141        /// <summary>
142        /// 清理所有正在使用的资源。
143        /// </summary>

144        protected override void Dispose( bool disposing )
145        {
146            if( disposing )
147            {
148                if( components != null )
149                    components.Dispose();
150            }

151            base.Dispose( disposing );
152        }

153
154        #region 组件设计器生成的代码
155        /// <summary>
156        /// 设计器支持所需的方法 - 不要使用代码编辑器 
157        /// 修改此方法的内容。
158        /// </summary>

159        private void InitializeComponent()
160        {
161        }

162        #endregion

163
164        /// <summary>
165        /// 重写OnPaint事件,执行画点操作
166        /// </summary>
167        /// <param name="pe"></param>

168        protected override void OnPaint(PaintEventArgs pe)
169        {
170            // TODO: 在此添加自定义绘画代码
171
172            // 调用基类 OnPaint
173            base.OnPaint(pe);
174            this.Text = "";
175            //paint three dot
176            
177            int loc = 5;
178            for (int i=0;i<(int)this.ipv-1;i++)
179            {
180                loc += this.sectLen;
181                pe.Graphics.DrawRectangle(Pens.Black,loc,(this.Height-this.sectHeight)/2+this.sectHeight-5,1,1);
182            }

183        }

184
185        /// <summary>
186        /// 响应控件改变大小事件,重画输入框
187        /// </summary>
188        /// <param name="sender"></param>
189        /// <param name="e"></param>

190        internal void IPTextBox_Resize(object sender, System.EventArgs e)
191        {
192            if (minLen > this.Width)
193            {
194                this.Width = minLen;
195            }

196            this.InitControl();
197        }

198
199        /// <summary>
200        /// 将焦点跳到下一个输入框
201        /// </summary>

202        internal void GoToNextSection()
203        {
204            if (this.currentFocused == null)
205            {
206                IPArray[0].Focus();
207                return;
208            }

209            for (int i=0;i<IPArray.Length;i++)
210            {
211                if (IPArray[i].Name.Equals(this.currentFocused.Name))
212                {
213                    if (i == IPArray.Length -1)
214                    {
215                        IPArray[i].Focus();
216                    }

217                    else
218                    {
219                        IPArray[i+1].Focus();
220                        IPArray[i+1].SelectionStart = 0;
221                    }

222                    break;
223                }

224            }

225        }

226
227        /// <summary>
228        /// 将焦点跳到上一个输入框
229        /// </summary>

230        internal void GoToLastSection()
231        {
232            if (this.currentFocused == null)
233            {
234                IPArray[0].Focus();
235                return;
236            }

237            for (int i=0;i<IPArray.Length;i++)
238            {
239                if (IPArray[i].Name.Equals(this.currentFocused.Name))
240                {
241                    if (i == 0)
242                    {
243                        IPArray[i].Focus();
244                        IPArray[i].SelectionStart = 0;
245                    }

246                    else
247                    {
248                        IPArray[i-1].Focus();
249                        IPArray[i-1].SelectionStart = (int)ipv-1;
250                    }

251                    break;
252                }

253            }

254        }

255
256        /// <summary>
257        /// 验证一个输入框的输入情况,并提示
258        /// </summary>
259        /// <param name="sender"></param>
260        /// <returns></returns>

261        public static bool ValidateIPSect(object sender)
262        {
263            string text = ((IPSection)sender).Text;
264            if (text == ""return false;
265            int ip = int.Parse(text);
266            if (((IPSection)sender).Name == ((IPTextBox)((IPSection)sender).Parent).IPArray[0].Name)
267            {
268                if (ip<firstMin || ip>firstMax)
269                {
270                    ((IPSection)sender).Text = firstMax.ToString();
271                    MessageBox.Show("IP地址必须在"+firstMin+""+firstMax+"之间");
272                    return false;
273                }

274            }

275            else
276            {
277                if (ip<otherMin || ip>otherMax)
278                {
279                    ((IPSection)sender).Text = otherMax.ToString();
280                    MessageBox.Show("IP地址必须在"+otherMin+""+otherMax+"之间");
281                    return false;
282                }

283            }

284            return true;
285        }

286
287        /// <summary>
288        /// 验证控件输入IP地址的有效性
289        /// </summary>

290        public void CompleteIPAddress()
291        {
292            for (int i=0;i<IPArray.Length;i++)
293            {
294                int ip = IPArray[i].Text.Length == 0?-1:int.Parse(IPArray[i].Text);
295                if (i == 0)
296                {
297                    if (ip<firstMin)
298                    {
299                        IPArray[i].Text = firstMin.ToString();
300                    }

301                    else if (ip>firstMax)
302                    {
303                        IPArray[i].Text = firstMax.ToString();
304                    }

305                }

306                else
307                {
308                    if (ip<otherMin)
309                    {
310                        IPArray[i].Text = otherMin.ToString();
311                    }

312                    else if (ip>otherMax)
313                    {
314                        IPArray[i].Text = otherMax.ToString();
315                    }

316                }

317            }

318        }

319    }

320}

以下是地址框中输入框对象:

  1using System;
  2using System.Collections;
  3using System.ComponentModel;
  4using System.Drawing;
  5using System.Data;
  6using System.Windows.Forms;
  7
  8namespace WindowsControlLibrary
  9{
 10    /// <summary>
 11    /// IPSection 的摘要说明。
 12    /// </summary>

 13    internal sealed class IPSection : System.Windows.Forms.TextBox
 14    {
 15        /// <summary>
 16        /// 必需的设计器变量。
 17        /// </summary>

 18        private System.ComponentModel.Container components = null;
 19        private static int width = 24;
 20        private static int height = 21;
 21
 22        internal IPSection()
 23        {
 24            // 该调用是 Windows.Forms 窗体设计器所必需的。
 25            InitializeComponent();
 26            InitControl();
 27            
 28            // TODO: 在 InitComponent 调用后添加任何初始化
 29        }

 30
 31        /// <summary>
 32        /// 初始化控件样式
 33        /// </summary>

 34        private void InitControl()
 35        {
 36            this.SuspendLayout();
 37            this.BorderStyle = BorderStyle.None;
 38            this.Width = 24;
 39            this.Height = 21;
 40            this.MaxLength = 3;
 41            this.ResumeLayout(false);
 42        }

 43
 44        /// <summary>
 45        /// 清理所有正在使用的资源。
 46        /// </summary>

 47        protected override void Dispose( bool disposing )
 48        {
 49            if( disposing )
 50            {
 51                if( components != null )
 52                    components.Dispose();
 53            }

 54            base.Dispose( disposing );
 55        }

 56
 57        #region 组件设计器生成的代码
 58        /// <summary>
 59        /// 设计器支持所需的方法 - 不要使用代码编辑器 
 60        /// 修改此方法的内容。
 61        /// </summary>

 62        private void InitializeComponent()
 63        {
 64            // 
 65            // IPSection
 66            // 
 67            this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.IPSection_KeyUp);
 68            this.Enter += new System.EventHandler(this.IPSection_Enter);
 69
 70        }

 71        #endregion

 72
 73        /// <summary>
 74        /// 取得控件的默认宽度
 75        /// </summary>
 76        /// <returns></returns>

 77        internal static int GetWidth()
 78        {
 79            return width;
 80        }

 81
 82        /// <summary>
 83        /// 取得控件的默认高度
 84        /// </summary>
 85        /// <returns></returns>

 86        internal static int GetHeight()
 87        {
 88            return height;
 89        }

 90
 91        /// <summary>
 92        /// 重画控件
 93        /// </summary>
 94        /// <param name="pe"></param>

 95        protected override void OnPaint(PaintEventArgs pe)
 96        {
 97            // TODO: 在此添加自定义绘画代码
 98
 99            // 调用基类 OnPaint
100            base.OnPaint(pe);
101        }

102
103        /// <summary>
104        /// 重写键盘响应事件,对部分键响应
105        /// </summary>
106        /// <param name="e"></param>

107        protected override void OnKeyPress(KeyPressEventArgs e)
108        {
109            //响应键盘事件
110            //LeftArrow 37,UpArrow 38,RightArrow 39,DownArrow 40
111            //Backspace 8
112            //0-9 48-57
113
114            base.OnKeyPress(e);
115            int key = e.KeyChar;
116            if (!(key == (char)8 || (key >=(char)37 && key <=(char)40|| (key >=(char)48 && key <=(char)57)))
117            {
118                e.Handled = true;
119            }

120        }

121
122        /// <summary>
123        /// 键盘响应事件,根据不同按键做出不同动作
124        /// </summary>
125        /// <param name="sender"></param>
126        /// <param name="e"></param>

127        private void IPSection_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
128        {
129            int key = e.KeyValue;
130            //长度等于3后,先验证有效性,然后跳到下一个输入段
131            if (this.Text.Length == 3)
132            {
133                if (!IPTextBox.ValidateIPSect(this))
134                {
135                    this.Focus();
136                    return;
137                }

138                ((IPTextBox)this.Parent).GoToNextSection();
139            }

140            
141            //按键按下"." 方向键右键 方向键下键
142            if (key == 190 || (key ==39 || key == 40&& (this.SelectionStart ==  this.Text.Length))
143            {
144                ((IPTextBox)this.Parent).GoToNextSection();
145            }

146
147            //按键按下退格键 方向键左键 方向键上键
148            if ((key == 8 || key ==37 || key == 38&& this.SelectionStart == 0)
149            {
150                ((IPTextBox)this.Parent).GoToLastSection();
151            }

152        }

153
154        /// <summary>
155        /// 在父控件中注册取得焦点的输入框
156        /// </summary>
157        /// <param name="sender"></param>
158        /// <param name="e"></param>

159        private void IPSection_Enter(object sender, System.EventArgs e)
160        {
161            ((IPTextBox)this.Parent).CurrentFocus = this;
162        }

163    }

164}


第一次写控件,多有不正确之处,请大家多多批评指正。
控件dll文件下载: IP地址输入框