在winform上放了20个动态textbox遇到的问题是左右下都没有问题

在winform上放了20个动态textbox(其中有部分enabled=false),然后加上按键事件,期望可以通过上下左右切换当前textbox的焦点,遇到的问题是左右下都没有问题,但是按UP键就是会回到最上方的一格去。求助是什么原因,code如下:


        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 10; i++)
            {
                TextBox textBox = new TextBox();
                textBox.AutoSize = false;
                textBox.Width = 80;
                textBox.Height = 20;
                textBox.TabIndex = 0;
                textBox.TabStop = false;
                if (i % 2 == 0)
                {
                    textBox.Enabled = false;
                }
                textBox.Name = "textBox1_" + (i + 1).ToString() + "_";
                textBox.KeyDown += new KeyEventHandler(textBox1_KeyDown);
                textBox.Location = new Point(100, 30 + i * 30);
                Controls.Add(textBox);
            }
            for (int i = 0; i < 10; i++)
            {
                TextBox textBox = new TextBox();
                textBox.AutoSize = false;
                textBox.Width = 80;
                textBox.Height = 20;
                textBox.TabIndex = 0;
                textBox.TabStop = false;
                if (i % 2 == 0)
                {
                    textBox.Enabled = false;
                }
                textBox.Name = "textBox2_" + (i + 1).ToString() + "_";
                textBox.KeyDown += new KeyEventHandler(textBox2_KeyDown);
                textBox.Location = new Point(300, 30 + i * 30);
                Controls.Add(textBox);
            }
        }
        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Right)
            {
                TextBox textBox = sender as TextBox;
                string number = GetValue(textBox.Name, "_", "_");
                foreach (Control c in Controls)
                {
                    if (c.Name == "textBox2_" + number + "_")
                    {
                        c.Select();
                    }
                }
            }
            if (e.KeyCode == Keys.Down)
            {
                TextBox textBox = sender as TextBox;
                string number = GetValue(textBox.Name, "_", "_");
                foreach (Control c in Controls)
                {
                    for (int i = int.Parse(number) + 1; i <= 10; i++)
                    {
                        if (c.Name == "textBox1_" + i.ToString() + "_")
                        {
                            if (c.Enabled)
                            {
                                c.Select();
                                return;
                            }
                        }
                    }
                }
            }
            if (e.KeyCode == Keys.Up)
            {
                TextBox textBox = sender as TextBox;
                string number = GetValue(textBox.Name, "_", "_");
                foreach (Control c in Controls)
                {
                    for (int i = int.Parse(number) - 1; i >= 1; i--)
                    {
                        if (c.Name == "textBox1_" + i.ToString() + "_")
                        {
                            if (c.Enabled)
                            {
                                c.Select();
                                return;
                            }
                        }
                    }
                }
            }
        }
        private void textBox2_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Left)
            {
                TextBox textBox = sender as TextBox;
                string number = GetValue(textBox.Name, "_", "_");
                foreach (Control c in Controls)
                {
                    if (c.Name == "textBox1_" + number + "_")
                    {
                        c.Select();
                    }
                }
            }
            if (e.KeyCode == Keys.Down)
            {
                TextBox textBox = sender as TextBox;
                string number = GetValue(textBox.Name, "_", "_");
                foreach (Control c in Controls)
                {
                    for (int i = int.Parse(number) + 1; i <= 10; i++)
                    {
                        if (c.Name == "textBox2_" + i.ToString() + "_")
                        {
                            if (c.Enabled)
                            {
                                c.Select();
                                return;
                            }
                        }
                    }
                }
            }
            if (e.KeyCode == Keys.Up)
            {
                TextBox textBox = sender as TextBox;
                string number = GetValue(textBox.Name, "_", "_");
                foreach (Control c in Controls)
                {
                    for (int i = int.Parse(number) - 1; i >= 1; i--)
                    {
                        if (c.Name == "textBox2_" + i.ToString() + "_")
                        {
                            if (c.Enabled)
                            {
                                c.Select();
                                return;
                            }
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 获得字符串中开始和结束字符串中间得值
        /// </summary>
        /// <param name="str">字符串</param>
        /// <param name="s">开始</param>
        /// <param name="e">结束</param>
        /// <returns></returns> 
        public static string GetValue(string str, string s, string e)
        {
            Regex rg = new Regex("(?<=(" + s + "))[.\\s\\S]*?(?=(" + e + "))", RegexOptions.Multiline | RegexOptions.Singleline);
            return rg.Match(str).Value;
        }
哇塞,搞的这么复杂。  在你的循环中 写textBox.TabIndex=i;  应该就可以实现你要求的功能了。

我不要tab切换,我想要在激活任意一个textbox的情况下能调到周围任意另一个textbox,tab只能按index的顺序切换下去

自定义个textbox继承系统的textbox,然后加几个属性,row,count,前提是你界面固定几行几列,弄个tableLayoutPanel固定好,初始化的时候循环放到容器的行列里面去,按上下的时候判断行列,加减一下,找到对应的textbox激活

把TextBox存在List里,开keyup事件,检测有上或下键(按下)弹起的时候,就把list里的textbox往前或往后取一个,设置它的Focus

你的循环逻辑有问题,foreach从小到大,你的for循环又是全部循环一遍,所以第一个text就匹配了。 你不如去掉for循环直接判断呢。如下就可以。


foreach (Control c in Controls)
                {
                    //for (int i = int.Parse(number) - 1; i >= 1; i--)
                    //{
                        if (c.Name == "textBox1_" + (int.Parse(number) - 2).ToString() + "_")
                        {
                            if (c.Enabled)
                            {
                                c.Select();
                                return;
                            }
                        //}
                    }
                }

 

foreach是为了寻找所有的动态控件,然后for是为了循环这些控件里面enabled的控件,因为我要跳过enabled=false的控件,不然 的话就只是周围一个textbox(如果这个textbox的enabled=false,那么根本无法focus)。for循环只是为了取可以 focus的控件(这也是为什么我要设置部分控件enabled=false的原因)。比如当前为第i个控件,如果第i-1个控件enabled,那么 focus这个控件然后返回,如果第i-1个控件enabled=false,那么for循环取i-2个控件……以此类推,直到取到的控件 enabled,focus之后才返回

你的循环逻辑有问题,foreach从小到大,你的for循环又是全部循环一遍,所以第一个text就匹配了。 你不如去掉for循环直接判断呢。如下就可以。


foreach (Control c in Controls)
                {
                    //for (int i = int.Parse(number) - 1; i >= 1; i--)
                    //{
                        if (c.Name == "textBox1_" + (int.Parse(number) - 2).ToString() + "_")
                        {
                            if (c.Enabled)
                            {
                                c.Select();
                                return;
                            }
                        //}
                    }
                }

你这样改成 (int.Parse(number) - 2).ToString() 纯粹只是一种特例(我简单设置了一个隔一个enabled=false),如果enabled的控件是随机的。就出错

就是UP中for循环去除,就OK拉

代码就简化很多,如下代码我测试了,是可以的。


        List<TextBox> mTxt = new List<TextBox> { };
        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 20; i++)
            {
                TextBox textBox = new TextBox();
                textBox.AutoSize = false;
                textBox.Width = 80;
                textBox.Height = 20;
                textBox.TabIndex = 0;
                textBox.TabStop = false;
                //if (i % 2 == 0)
                //{
                //    textBox.Enabled = false;
                //}
                textBox.Name = "textBox_" + (i + 1).ToString();
                textBox.KeyDown += new KeyEventHandler(textBox1_KeyDown);
                textBox.Location = new Point(100, 30 + i * 30);
                if (i >= 10)
                {
                    textBox.Location = new Point(300, 30 + (i - 10) * 30);
                }
                mTxt.Add(textBox);

                Controls.Add(textBox);
            }
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            int number = int.Parse(((TextBox)sender).Name.Substring(8, ((TextBox)sender).Name.Length - 8)) - 1;
            switch (e.KeyCode)
            {
                case Keys.Right:
                    if (number <= 9)
                    {
                        mTxt[number + 10].Focus();
                    }
                    break;
                case Keys.Left:
                    if (number > 9)
                    {
                        mTxt[number - 10].Focus();
                    }
                    break;
                case Keys.Up:
                    if (number != 0)
                    {
                        mTxt[number - 1].Focus();
                    }
                    break;
                case Keys.Down:
                    if (number != 19)
                    {
                        mTxt[number + 1].Focus();
                    }
                    break;
            }

        }
你可以用一个二维数组保存动态的控件。这样更容易操作一些。
用一个point来记录当前具有焦点的控件,当按键时,用一个point来收集按键:

        Dim newrc As Point = currc
        Dim dir As Point = Point.Empty
        If e.KeyData = Keys.Up Then dir.X = -1
        If e.KeyData = Keys.Down Then dir.X = 1
        If e.KeyData = Keys.Left Then dir.Y = -1
        If e.KeyData = Keys.Right Then dir.Y = 1
        If dir <> Point.Empty Then
            Do
                newrc += dir
                '如果newrc不在r,c范围内,退出循环——超出矩形边缘
                '如果newrc所代表的控件enabled,则currc=newrc并将焦点放在当前坐标上的控件
            Loop
        End If

如果要跳过enabled=false, 学你一样,加个循环判断,哈哈


        List<TextBox> mTxt = new List<TextBox> { };
        private void Form1_Load(object sender, EventArgs e)
        {
            for (int i = 0; i < 20; i++)
            {
                TextBox textBox = new TextBox();
                textBox.AutoSize = false;
                textBox.Width = 80;
                textBox.Height = 20;
                textBox.TabIndex = 0;
                textBox.TabStop = false;
                if (i % 3 == 0)
                {
                    textBox.Enabled = false;
                }
                textBox.Name = "textBox_" + (i + 1).ToString();
                textBox.KeyDown += new KeyEventHandler(textBox1_KeyDown);
                textBox.Location = new Point(100, 30 + i * 30);
                if (i >= 10)
                {
                    textBox.Location = new Point(300, 30 + (i - 10) * 30);
                }
                mTxt.Add(textBox);

                Controls.Add(textBox);
            }
        }

        private void textBox1_KeyDown(object sender, KeyEventArgs e)
        {
            int number = int.Parse(((TextBox)sender).Name.Substring(8, ((TextBox)sender).Name.Length - 8)) - 1;
            switch (e.KeyCode)
            {
                case Keys.Right:
                    if (number <= 9)
                    {
                        mTxt[number + 10].Focus();
                    }
                    break;
                case Keys.Left:
                    if (number > 9)
                    {
                        mTxt[number - 10].Focus();
                    }
                    break;
                case Keys.Up:
                    while ((number - 1) > 0 && mTxt[number - 1].Enabled==false )
                    {
                        number--;
                    }
                    mTxt[number - 1].Focus();
                    break;
                case Keys.Down:
                    while ((number + 1) < 18 && mTxt[number + 1].Enabled == false)
                    {
                        number++;
                    }
                    mTxt[number + 1].Focus();
                    break;
            }

        }
 

虽然和我预期的效果还有那么一点点差距。不过方法不错,我考虑一下怎么修改一下。另外UP和DOWN的逻辑稍微论坛发帖机有点问题,18的话有的情况取不到最后一个 textbox,19的话focus的时候算加减会超出数组下标,改成先判断加减1是否超出下标,对number修改之后再focus才行。还是谢谢了

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值