wpf 如何创建一个带 IP 地址输入的掩码文本框?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24549197/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 12:04:08  来源:igfitidea点击:

How to create a masked TextBox for taking IP Address input?

c#wpf

提问by Abhishek

I am trying to create a masked TextBox for taking input similar to IP Address. I dont want to use the third party controls and want to develop my own. Can someone guide me in the right direction?

我正在尝试创建一个屏蔽的 TextBox 以获取类似于 IP 地址的输入。我不想使用第三方控件,想开发自己的控件。有人可以指导我朝着正确的方向前进吗?

I have managed to restrict the keyboard entry to digits. How do I add the ( . . . ) mask?

我设法将键盘输入限制为数字。如何添加 ( . . ) 掩码?

回答by pushpraj

If you are very keen to develop your own control for the same. You may have to handle the key event and render the value according to specified mask

如果您非常热衷于开发自己的控件。您可能需要处理按键事件并根据指定的掩码呈现值

here is a similar masked textbox from wpf toolkit

这是来自 wpf 工具包的类似蒙版文本框

https://wpftoolkit.codeplex.com/SourceControl/latest#Main/Source/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs

https://wpftoolkit.codeplex.com/SourceControl/latest#Main/Source/ExtendedWPFToolkitSolution/Src/Xceed.Wpf.Toolkit/MaskedTextBox/Implementation/MaskedTextBox.cs

this link provide complete implementation, you may have a look and develop your own

此链接提供完整的实现,您可以查看并开发自己的

回答by Max Euwe

I was surprised there wasn't something recent, or at least halfway decent for Windows Forms in c# that solved this problem even to the point that it could be polished into something maintainable without returning to Windows 3.1 syntax, cmds, msgs, lpcstrs. importing dlls, and such.

我很惊讶 C# 中的 Windows 窗体最近没有或至少有一半像样的东西可以解决这个问题,甚至可以将它打磨成可维护的东西,而无需返回到 Windows 3.1 语法、cmds、msgs、lpcstrs。导入dll等。

I created a control out of 4 textboxes, three bitmaps (dots) MSDN application notes, and some key event handlers. Rejecting non-digits wasn't hard, truncating the text string to three characters in insert mode wasn't hard, but it took a little trial and error to find a combination that allowed smooth transition between the text boxes on enter and tab key presses. It was a little frustrating getting the last text box to transfer focus to the next control in the form.

我用 4 个文本框、三个位图(点)MSDN 应用程序注释和一些关键事件处理程序创建了一个控件。拒绝非数字并不难,在插入模式下将文本字符串截断为三个字符并不难,但需要一些试验和错误才能找到一种组合,允许在 Enter 和 Tab 键按下时在文本框之间平滑过渡. 让最后一个文本框将焦点转移到表单中的下一个控件有点令人沮丧。

As always, tab and enter are handled differently, and do things under the covers between key down and keypress - I had to guess at what was happening, since I don't have any fancy step-through source libraries.

与往常一样,tab 和 enter 的处理方式不同,并且在 key down 和 keypress 之间做一些隐藏的事情 - 我不得不猜测发生了什么,因为我没有任何花哨的逐步源库。

Anyway, here's my solution. I wrote it yesterday, and tested it today. I have a demo tomorrow, wish me luck.

无论如何,这是我的解决方案。昨天写的,今天测试了一下。我明天有一个演示,祝我好运。

    using System;
using System.Drawing;
using System.Net;
using System.Windows.Forms;
using Framework.UserApplication.Utility;

namespace Framework.UserApplication.CommonDialogs
{
    /**************************************************************************************************
     * A TCP IP input mask.
     * sealed because of virtual member calls in constructor
     *  By having a virtual call in an object's constructor you are introducing the possibility that
     *  inheriting objects will execute code before they have been fully initialized.
     **************************************************************************************************/

    public sealed partial class TcpIpInputMaskType : UserControl
    {
        private bool _hasFocus; // True if this TcpIpInputMaskType has focus

        private IPAddress _ipAddress; // The IP address
        private bool _showFocusRect; // True to show, false to hide the focus rectangle

        /**************************************************************************************************
         * Default constructor.
         **************************************************************************************************/

        public TcpIpInputMaskType()
        {
            _showFocusRect = ShowFocusCues;
            _hasFocus = false;
            InitializeComponent();
            ChangeUICues += IpTextBoxes_ChangeUiCues;
            BackColor = Color.Transparent;
            AutoSize = true;
        }

        /**************************************************************************************************
         * Gets the IP address.
         *
         * @return  The IP address.
         **************************************************************************************************/

        public IPAddress IpAddress
        {
            get
            {
                try
                {
                    _ipAddress = new IPAddress(new[]
                    {
                        Convert.ToByte(IP1.Text), Convert.ToByte(IP2.Text),
                        Convert.ToByte(IP3.Text), Convert.ToByte(IP4.Text)
                    });
                }
                catch (Exception e)
                {
                    _ipAddress = null;
                    Console.WriteLine(e);
                }

                return _ipAddress;
            }
        }

        /**************************************************************************************************
         * Gets the IP address hex string.
         *
         * @return  The IP hex address string.
         **************************************************************************************************/

        public string IpAddressHexString
        {
            get
            {
                if (IpAddress == null)
                    return "";

                var barry = new[]
                {
                    Convert.ToByte(IP1.Text),
                    Convert.ToByte(IP2.Text),
                    Convert.ToByte(IP3.Text),
                    Convert.ToByte(IP4.Text)
                };
                return AsciiHexConversionType.ByteArrayToHexWithSpaces(barry);
            }
        }

        /**************************************************************************************************
         * Gets the dotted IP address string.
         *
         * @return  The dotted IP address string.
         **************************************************************************************************/

        public string DottedIpAddressString
        {
            get
            {
                if (_ipAddress == null)
                    return "";

                return IpAddress.ToString();
            }
        }

        /**************************************************************************************************
         * Gets the ulong IP address.
         *
         * @return  The ulong IP address.
         **************************************************************************************************/

        public ulong UlongIpAddress
        {
            get
            {
                if (IpAddress == null)
                    return 0;

                var address = (ulong) (Convert.ToByte(IP1.Text) * (256 ^ 3)) +
                              (ulong) (Convert.ToByte(IP2.Text) * (256 ^ 2)) +
                              (ulong) (Convert.ToByte(IP3.Text) * 256) + Convert.ToByte(IP4.Text);
                return address;
            }
        }

        /**************************************************************************************************
         * Change focus.
         *
         * @param   ipTextBox   The IP control.
         **************************************************************************************************/

        private void ChangeFocus(TextBox ipTextBox)
        {
            switch (ipTextBox.Name)
            {
                case "IP1":
                    IP2.Select();
                    break;
                case "IP2":
                    IP3.Select();
                    break;
                case "IP3":
                    IP4.Select();
                    break;
                case "IP4":
                    ipTextBox.SelectNextControl(ActiveControl, true, true, true, true);
                    break;
            }
        }

        /**************************************************************************************************
         * Event handler. Called by IP1 for key press events.
         *
         * @param   sender  Source of the event.
         * @param   e       Key press event information.
         **************************************************************************************************/

        private void IP1_KeyPress(object sender, KeyPressEventArgs e)
        {
            var ipTextBox = sender as TextBox;
            switch (e.KeyChar)
            {
                case '\r':
                    SendKeys.Send("{TAB}");
                    e.Handled = true;
                    return;
                case '\t':
                    if (ipTextBox != null)
                        ChangeFocus(ipTextBox);
                    e.Handled = true;
                    break;
                default:
                    if (!char.IsDigit(e.KeyChar))
                        e.Handled = true;
                    break;
            }
        }

        /**************************************************************************************************
         * Event handler. Called by IP1 for text changed events.
         *
         * @param   sender  Source of the event.
         * @param   e       Event information.
         **************************************************************************************************/

        private void IP1_TextChanged(object sender, EventArgs e)
        {
            var ipTextBox = sender as TextBox;
            if (ipTextBox != null && ipTextBox.TextLength == 4)
            {
                ipTextBox.Text = ipTextBox.Text.Substring(0, 3);
                return;
            }

            if (ipTextBox != null && ipTextBox.TextLength == 3)
                ChangeFocus(ipTextBox);
        }

        /**************************************************************************************************
         * Event handler. Called by IP4 for key down events.
         *
         * @param   sender  Source of the event.
         * @param   e       Key event information.
         **************************************************************************************************/

        private void IP4_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                SendKeys.Send("{TAB}");
                e.Handled = true;
                e.SuppressKeyPress = true;
            }
        }

        /**************************************************************************************************
         * Event handler. Called by IpTextBoxes for change user interface cues events.
         *
         * @param   sender  Source of the event.
         * @param   e       User interface cues event information.
         **************************************************************************************************/

        private void IpTextBoxes_ChangeUiCues(object sender, UICuesEventArgs e)
        {
            _showFocusRect = e.ShowFocus;
        }

        /**************************************************************************************************
         * Raises the <see cref="E:System.Windows.Forms.Control.Enter" />
         *  event.
         *
         * @param   e   An <see cref="T:System.EventArgs" />
         *               that contains the event data.
         **************************************************************************************************/

        protected override void OnEnter(EventArgs e)
        {
            Invalidate();
        }

        /**************************************************************************************************
         * Raises the <see cref="E:System.Windows.Forms.Control.Leave" />
         *  event.
         *
         * @param   e   An <see cref="T:System.EventArgs" />
         *               that contains the event data.
         **************************************************************************************************/

        protected override void OnLeave(EventArgs e)
        {
            Invalidate();
        }

        /**************************************************************************************************
         * Raises the <see cref="E:System.Windows.Forms.Control.LostFocus" />
         *  event.
         *
         * @param   e   An <see cref="T:System.EventArgs" />
         *               that contains the event data.
         **************************************************************************************************/

        protected override void OnLostFocus(EventArgs e)
        {
            _hasFocus = false;
        }

        /**************************************************************************************************
         * Raises the <see cref="E:System.Windows.Forms.Control.Paint" />
         *  event.
         *
         * @param   e   A <see cref="T:System.Windows.Forms.PaintEventArgs" />
         *               that contains the event data.
         **************************************************************************************************/

        protected override void OnPaint(PaintEventArgs e)
        {
            var focusRect = ClientRectangle;
            focusRect.Inflate(-2, -2);
            if (_hasFocus && _showFocusRect)
                ControlPaint.DrawFocusRectangle(e.Graphics, focusRect, ForeColor, BackColor);
            else
                e.Graphics.DrawRectangle(new Pen(BackColor, 1), focusRect);
            base.OnPaint(e);
        }

        /**************************************************************************************************
         * Sets default IP address.
         *
         * @param   ip1 The first IP.
         * @param   ip2 The second IP.
         * @param   ip3 The third IP.
         * @param   ip4 The fourth IP.
         *
         * @return  The IPAddress.
         **************************************************************************************************/

        public IPAddress SetDefaultIpAddress(string ip1, string ip2, string ip3, string ip4)
        {
            IP1.Text = ip1;
            IP2.Text = ip2;
            IP3.Text = ip3;
            IP4.Text = ip4;
            return IpAddress;
            }
        }

}

here's the designer code

这是设计器代码

namespace Framework.UserApplication.CommonDialogs
{
    sealed partial class TcpIpInputMaskType
    {
        /// <summary> 
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Component Designer generated code

        /// <summary> 
        /// Required method for Designer support - do not modify 
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.pictureBox5 = new System.Windows.Forms.PictureBox();
            this.pictureBox4 = new System.Windows.Forms.PictureBox();
            this.pictureBox3 = new System.Windows.Forms.PictureBox();
            this.IP2 = new System.Windows.Forms.TextBox();
            this.IP3 = new System.Windows.Forms.TextBox();
            this.IP4 = new System.Windows.Forms.TextBox();
            this.IP1 = new System.Windows.Forms.TextBox();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox5)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).BeginInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).BeginInit();
            this.SuspendLayout();
            // 
            // pictureBox5
            // 
            this.pictureBox5.Image = global::Framework.Properties.Resources.dot1;
            this.pictureBox5.Location = new System.Drawing.Point(87, 26);
            this.pictureBox5.Name = "pictureBox5";
            this.pictureBox5.Size = new System.Drawing.Size(5, 5);
            this.pictureBox5.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this.pictureBox5.TabIndex = 91;
            this.pictureBox5.TabStop = false;
            // 
            // pictureBox4
            // 
            this.pictureBox4.Image = global::Framework.Properties.Resources.dot1;
            this.pictureBox4.Location = new System.Drawing.Point(57, 25);
            this.pictureBox4.Name = "pictureBox4";
            this.pictureBox4.Size = new System.Drawing.Size(5, 5);
            this.pictureBox4.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this.pictureBox4.TabIndex = 90;
            this.pictureBox4.TabStop = false;
            // 
            // pictureBox3
            // 
            this.pictureBox3.Image = global::Framework.Properties.Resources.dot1;
            this.pictureBox3.Location = new System.Drawing.Point(29, 25);
            this.pictureBox3.Name = "pictureBox3";
            this.pictureBox3.Size = new System.Drawing.Size(5, 5);
            this.pictureBox3.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;
            this.pictureBox3.TabIndex = 89;
            this.pictureBox3.TabStop = false;
            // 
            // IP2
            // 
            this.IP2.Location = new System.Drawing.Point(32, 5);
            this.IP2.Name = "IP2";
            this.IP2.Size = new System.Drawing.Size(27, 20);
            this.IP2.TabIndex = 86;
            this.IP2.TextChanged += new System.EventHandler(this.IP1_TextChanged);
            this.IP2.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.IP1_KeyPress);
            // 
            // IP3
            // 
            this.IP3.Location = new System.Drawing.Point(61, 5);
            this.IP3.Name = "IP3";
            this.IP3.Size = new System.Drawing.Size(27, 20);
            this.IP3.TabIndex = 87;
            this.IP3.TextChanged += new System.EventHandler(this.IP1_TextChanged);
            this.IP3.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.IP1_KeyPress);
            // 
            // IP4
            // 
            this.IP4.Location = new System.Drawing.Point(90, 5);
            this.IP4.Name = "IP4";
            this.IP4.Size = new System.Drawing.Size(27, 20);
            this.IP4.TabIndex = 88;
            this.IP4.TextChanged += new System.EventHandler(this.IP1_TextChanged);
            this.IP4.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.IP1_KeyPress);
            // 
            // IP1
            // 
            this.IP1.Location = new System.Drawing.Point(3, 5);
            this.IP1.Name = "IP1";
            this.IP1.Size = new System.Drawing.Size(27, 20);
            this.IP1.TabIndex = 85;
            this.IP1.TextChanged += new System.EventHandler(this.IP1_TextChanged);
            this.IP1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.IP4_KeyDown);
            this.IP1.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.IP1_KeyPress);
            // 
            // TcpIpInputMaskType
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
            this.BackColor = System.Drawing.Color.Transparent;
            this.Controls.Add(this.pictureBox5);
            this.Controls.Add(this.pictureBox4);
            this.Controls.Add(this.pictureBox3);
            this.Controls.Add(this.IP2);
            this.Controls.Add(this.IP3);
            this.Controls.Add(this.IP4);
            this.Controls.Add(this.IP1);
            this.Name = "TcpIpInputMaskType";
            this.Size = new System.Drawing.Size(126, 31);
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox5)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox4)).EndInit();
            ((System.ComponentModel.ISupportInitialize)(this.pictureBox3)).EndInit();
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #endregion

        private System.Windows.Forms.PictureBox pictureBox5;
        private System.Windows.Forms.PictureBox pictureBox4;
        private System.Windows.Forms.PictureBox pictureBox3;
        private System.Windows.Forms.TextBox IP2;
        private System.Windows.Forms.TextBox IP3;
        private System.Windows.Forms.TextBox IP4;
        private System.Windows.Forms.TextBox IP1;
    }
}

here is "dot1" in my project, the background is transparent. It's a little hinky when there's more than one thing behind it, but you can match the color in the designer, no problem.

这是我项目中的“dot1”,背景是透明的。当它背后有不止一个东西时,这有点麻烦,但是您可以在设计器中匹配颜色,没问题。

If I run into anything, I'll come back and edit this post.

如果我遇到任何问题,我会回来编辑这篇文章。

dot1.png

dot1.png

回答by islam elgaidi

****This is the perfect way .** there is a native Win32 control that supports handling of IP Addresse

****这是完美的方法。** 有一个支持处理 IP 地址的本机 Win32 控件

  public class IPTextBox : TextBox
        {
            public IPTextBox() : base()
            {

            }

            protected override CreateParams CreateParams
            {
                get
                {
                    new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
                    CreateParams cp = base.CreateParams;
                    cp.ClassName = "SysIPAddress32";
                    return cp;
                }
            }


        }

回答by Complexity

Windows WPF includes this already. No need to re-invent the wheel.

Windows WPF 已经包含了这个。无需重新发明轮子。

Imports needed:

需要进口:

System.Net.IPAddress
System.Windows.Forms.MaskedTextBox

Now, you need to set the properties:

现在,您需要设置属性:

MaskedTextBox.Mask = ###.###.###.### 
MaskedTextBox.ValidatingType = typeof(System.Net.IPAddress);