我要在C# Windows Forms 中自定义TextBox控件,按要求:(1)这个TextBox控件的最大长度为32767(int型),要求当输入的长度大于32767时TextBox就不能再输入了(不过此时可以删除);(2)另外,假设TextBox的长度为6,在粘贴数据之前TextBox中已经有1234四位数字,现在当光标位于2、3之间时我要粘贴567这个数字进TextBox(因为TextBox假设的最大长度为6),所以在粘贴数据时只能把56粘进去,数据最终变成“125634”(粘贴时光标可位于文本框任何位置)。请问高手如何实现这两个功能?

解决方案 »

  1.   

    设置TextBox的MaxLength属性:textBox1.MaxLength = 6;
      

  2.   


    (1)
    textBox1.MaxLength = 32767;
    (2)
    设置了(1)之后,就达到了(2)的要求。
      

  3.   

    楼主没有试一下设置textBox1.MaxLength = 6;后的效果吗?已经可以控制粘贴的字符数了。
      

  4.   

    因为开始没有分嘛,所以这次多拿些出来。不过只是设置MaxLength的属性还远远不够啊,我在程序中已经设置了,但在粘贴时无法自动剪掉超出长度的数字部分。
    另外,这个自定义TextBox控件是专门用来输入金额的。
      

  5.   

    (1)        private void textBox1_TextChanged(object sender, EventArgs e)
            {
                if (textBox1.Text.Length > 32767)
                {
                    return;
                }
            }
    第(2)个问题,有点难度,我要获取Ctrl+V的值,现在还没找到方法.先别结贴
      

  6.   

    http://www.cnblogs.com/lemony/archive/2007/04/10/707474.html
      

  7.   

    我们先新建一个组件 TextBoxEx,继承于 TextBox ,增加一个 MaxByteLength  属性
    public partial class TextBoxEx : TextBox
        {
            public TextBoxEx()
            {
                InitializeComponent();
            }        属性#region 属性        private int m_MaxByteLength = 0;
            [Description("获取或设置用户可在文本框控件中键入或粘贴的最大字节数。0 为允许无限长度。")]
            /**//// <summary>
            /// 获取或设置用户可在文本框控件中键入或粘贴的最大字节数。0 为允许无限长度。
            /// </summary>
            public int MaxByteLength
            {
                get { return m_MaxByteLength; }
                set { m_MaxByteLength = value; }
            }
    }
    然后重写 WndProc ,实现输入和粘贴的时候对字节长度进行判断
            protected override void WndProc(ref Message m)
            {
                //如果该属性没有设置,则允许输入
                if (m_MaxByteLength == 0)
                {
                    base.WndProc(ref m);
                    return;
                }            switch (m.Msg)
                {
                    case WM_CHAR:
                        int i = (int)m.WParam;
                        bool isBack = (i == (int)Keys.Back);
                        bool isCtr = (i == 24) || (i == 22) || (i == 26) || (i == 3);                    if (isBack || isCtr)
                        {
                            //控制键不作处理
                        }
                        else
                        {
                            char c = (char)i;
                            if (CheckByteLengthFlow(c.ToString()))
                            {
                                break;
                            }
                        }
                        base.WndProc(ref m);
                        break;
                    case WM_PASTE:
                        IDataObject iData = Clipboard.GetDataObject();//取剪贴板对象
                        if (iData.GetDataPresent(DataFormats.Text)) //判断是否是Text
                        {
                            string text = (string)iData.GetData(DataFormats.Text);//取数据
                            if (CheckByteLengthFlow(text))
                            {
                                m.Result = (IntPtr)0;//不可以粘贴
                                break;
                            }
                        }
                        base.WndProc(ref m);
                        break;
                    default:
                        base.WndProc(ref m);
                        break;
                }
            }        /// <summary>
            /// 判断即将输入的文本长度是否溢出
            /// </summary>
            /// <param name="text">文本</param>
            /// <returns>是否溢出</returns>
            private bool CheckByteLengthFlow(string text)
            {
                int len = GetByteLength(text);    //输入的字符的长度
                int tlen = GetByteLength(this.Text);  //文本框原有文本的长度
                int slen = GetByteLength(this.SelectedText);    //文本框选中文本的长度
                return (m_MaxByteLength < (tlen - slen + len));
            }        /// <summary>
            /// 计算文本字节长度,区分多字节字符
            /// </summary>
            /// <param name="text">文本</param>
            /// <returns>文本字节长度</returns>
            private int GetByteLength(string text)
            {
                return System.Text.Encoding.Default.GetBytes(text).Length;
            }另外,增加一个 RealText 属性,该属性返回具有合法长度的文本, 不会截断多字节字符
    public string RealText
            {
                get
                {
                    if (m_MaxByteLength == 0)
                    {
                        return this.Text;
                    }                if (m_MaxByteLength >= GetByteLength(this.Text))
                    {
                        return this.Text;
                    }                string text = this.Text;                if (string.IsNullOrEmpty(text))
                    {
                        return text;
                    }                char[] c = text.ToCharArray();
                    StringBuilder sb = new StringBuilder();
                    int count = 0;                for (int i = 0; i < c.Length; i++)
                    {
                        count += GetByteLength(c[i].ToString());
                        if (m_MaxByteLength >= count)
                        {
                            sb.Append(c[i]);
                        }
                    }                return sb.ToString();
                }
            }
      

  8.   

    看了下13楼的代码可以不过有点建意你不要自己再重写控件了,用他那代码直接在原有的TEXTBOX上就可以实现
      

  9.   

    请问一下12楼的牛人:  HDNGO:    WM_CHAR和WM_PASTE的值是多少啊?急求!
      

  10.   

    WM_CHAR消息是俘获某一个字符的消息,WM_KEYDOWN消息是俘获某一个键按下的消息 
    假如分别按下“q”和“shift+q”,发出的WM_KEYDOWN消息都是代表q键,而发出的WM_CHAR消息分别是“q”和“Q” PS:俺挫。。那个地址只不过是我收藏一个地址罢了~
      

  11.   

    我在编译时,因为WM_CHAR和WM_PASTE的值没有进行设置,所以无法运行啊。
      

  12.   

    我在编译时,因为WM_CHAR和WM_PASTE的值没有进行设置,所以无法运行啊。
      

  13.   

    给你demo~
    http://files.cnblogs.com/lemony/TextBoxExTest_OLD.rar