在C# Windows中更改文本框中的光标位置

8

我有一个加载MDI子窗体的WinForm。子窗体中所有文本框的光标始终停留在左侧,我无法将其移动到其他位置,除非选择所有文本并重新输入。

如何启用此功能以使鼠标可以使光标停留在任何位置?


对于每个文本框,尝试将SelectionStart = i和SelectionLength = 0,其中i是所需的光标位置。 - kol
我该如何为所有文本框设置?因为我有很多文本框 :( - vNext
1
使用循环 :) 表单有一个名为 Controls 的属性,它是一个 ControlCollection。您可以使用 foreach (var c in form.Controls) 迭代其元素,使用 TextBox tb = c as TextBox; if (tb != null) ... 测试当前控件是否为 TextBox,并为 tb 设置光标位置。 - kol
这意味着没有办法设置它。例如,Win Form 的属性?我们必须手动完成 :( - vNext
3个回答

12
在下面的例子中,光标将定位在表单中每个文本框的第二个字符之后。焦点将在最后一个文本框上,但是通过反复按TAB键,您可以验证已为每个文本框设置了光标位置。
using System;
using System.Windows.Forms;

public class Program
{
  public static void Main()
  {
    var form = new Form();
    form.Text = "Cursor Positioning Test";
    form.Visible = true;
    form.Shown += delegate(object sender, EventArgs args) {
      foreach (var control in form.Controls)
      {
        var textBox = control as TextBox;
        if (textBox != null)
        {
          textBox.Focus();
          textBox.SelectionStart = 2;
          textBox.SelectionLength = 0;
        }
      }
    };

    var textBox1 = new TextBox();
    textBox1.Text = "hello";
    textBox1.Left = 10;
    textBox1.Top = 10;
    form.Controls.Add(textBox1);

    var textBox2 = new TextBox();
    textBox2.Text = "stack";
    textBox2.Left = 10;
    textBox2.Top = 10 + textBox1.Height + 10;
    form.Controls.Add(textBox2);

    var textBox3 = new TextBox();
    textBox3.Text = "overflow";
    textBox3.Left = 10;
    textBox3.Top = 10 + textBox1.Height + 10 + textBox2.Height + 10;
    form.Controls.Add(textBox3);

    Application.Run(form);
  }
}

kol,很好,但如果您在foreach中执行以下操作: foreach(TextBox control in form.Controls),那么您将不需要这个: var textBox = control as TextBox;请注意,我尚未测试它,但我认为它应该可以工作。 - Pavel Donchev
@PavelDonchev,您的想法只有在所有控件都是文本框时才有效。如果表单上还有一个按钮,那么您会收到一个异常,提示无法将 System.Windows.Forms.Button 转换为 System.Windows.Forms.TextBox。 - kol
我不太确定你是对的。 我刚刚创建了一个带有按钮和文本框的表单,然后编写了以下内容: foreach (TextBox tb in this.Controls) { MessageBox.Show(tb.Name); }并且执行它并获取表单上文本框的名称没有任何问题,它只是跳过了按钮。 如果您无法正常工作,非常感兴趣-为什么无法正常工作。 我在Windows Forms、Visual Studio 2010、.NET Framework 4 Client Profile(我的默认设置)上尝试了它。很抱歉必须在评论中编写代码,我知道它看起来不好。 - Pavel Donchev
@PavelDonchev 我用上述代码测试了你的想法,并进行了两个修改:(1)添加了一个按钮(var button = new Button(); form.Controls.Add(button);),(2)将 form.Shown 事件处理程序委托更改为 foreach (TextBox textBox in form.Controls) { textBox.Focus(); textBox.SelectionStart = 2; textBox.SelectionLength = 0; }。后者会引发我上面提到的异常。 - kol
你是对的。 现在我注意到为什么它会欺骗我。 在Shown事件处理程序中,进程被终止(如果您正在调试,则Visual Studio会弹出一个窗口,显示带有Invalid Cast Exception的行)。 如果您尝试将代码放入Load事件处理程序中,您会注意到表单将正常加载(除非它不按预期工作)。如果您将代码放入try..catch块中,仍然可以捕获InvalidCastException。非常奇怪的行为。 - Pavel Donchev

9

试一下这个,希望对你有所帮助;)

//if you want put cusror at the end of text use this:
TextBox1.SelectionStart = TextBox1.Text.Length;
TextBox1.SelectionLength = 0;
//use this for custom location  int CustomIndex 
TextBox1.SelectionStart = CustomIndex;
TextBox1.SelectionLength = 0;

1

//这是一个关于Windows表单中带有'##.####'掩码的maskedTextBox从右到左输入测试,其为decimal(6,4)类型的内容。

private void maskedTextBoxMaskRTF_KeyPress(object sender, KeyPressEventArgs e) {

        var maskedTextBox = (MaskedTextBox)sender;

        var contLit = maskedTextBox.Text.Where(ch => ".,".Contains(ch)).Count();

        var value = maskedTextBox.Text.Replace(".", "").Replace(",", "") + e.KeyChar;

        if (value.Length >= maskedTextBox.Mask.Length - contLit)
            value = value.Substring(1);
        else
            while (value.Length < maskedTextBox.Mask.Length - contLit)
                value = "_" + value;

        maskedTextBox.Text = value;
        maskedTextBox.SelectionStart = maskedTextBox.Mask.Length - 1;
        maskedTextBox.SelectionLength = 1;           
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接