且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

插入新的RichTextBox行后,为什么我不能继续输入文字?

更新时间:2023-12-03 16:53:16

请参阅我对该问题的评论。我已经为你做了;所有代码如果完全可运行且工作正常,从第一次尝试开始:

Please see my comment to the question. I have done it for your; all code if fully runnable and works correctly, from the first attempt:
using System;
using System.Windows.Forms;

class MyForm : Form {
    internal MyForm() {
        RichTextBox tb = new RichTextBox();
        string myText = string.Format("some{0}program{0}code(0) {{}}", "\n");
        tb.Text = myText;
        tb.Dock = DockStyle.Fill;
        tb.Parent = this;
        Shown += (sender, eventArgs) => {
            tb.Focus();
            tb.SelectionStart = myText.Length - 1;
        };
    }
}

static class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new MyForm());
    }
}



您的主要错误是使用 Environment.NewLine 。这太棒了:大多数人都使用它并建议使用它,但这是错误的。富文本实际上是多平台格式,并且它的通用新行指示符对于所有平台(环境)都是相同的,并且这只是一个字符,而不是Windows上的两个字符(\\\\ n) 。



实际上,在这个电话中添加什么字符并不重要;实验表明\ n或\r都有效。这是修复它的许多UI API的典型特征。问题只是估计插入点的位置。它应该考虑到新的只有一个字符,而不是两个字符。是的,这是一个微妙的问题... :-)



当然你想要硬编码你的52是错的,以及使用字符串连接的想法。字符串是不可变的,所以重复连接很糟糕(我甚至需要解释原因),但更重要的是,你的代码是不可维护的。



一个更重要的细节:为什么我把焦点和光标位置的变化放在显示的事件的事件处理程序中?您可以看到,在这种情况下,如果将其移动到构造代码中,它将起作用,而无需事件处理。但总的来说,现在还为时尚早。特别是,聚焦尚未显示的东西是不可能的。







另外,请查看我的代码示例,以便了解如何提问,如何提供100%的代码。此代码是完整的代码文件,这是整个应用程序中唯一的一个文件。我摆脱了设计师生成的代码,一切都帮助我在这个简短的样本中创建了整个应用程序。



如果你试图通过编写这么小的单独的应用程序来隔离你的问题,很可能,你会更清楚地看到问题,所以你可以自己解决它。如果没有,这样的代码适合在CodeProject问题中发布。



-SA


Your main mistake was using Environment.NewLine. It's amazing: most people use it and advise to use it, but it's wrong. Rich text is actually the multiplatform format, and it has its universal new line indicator the same for all the platforms ("Environments"), and this is only one character, not two as on Windows ("\r\n").

Actually, it's not even important what character to add in this call; experiments show that either "\n" or "\r" works. This is typical for many UI APIs where it is fixed. The problem is just the estimate of the position where you put insertion point. It should take into account that new like is only one character, not two. Yes, this is a delicate problem… :-)

And of course you idea to hard code your 52 is wrong, as well as the idea to use string concatenation. String is immutable, so repeated concatenation is bad (do I even need to explain why), but, more importantly, your code is not maintainable.

One more important detail: why did I put focusing and the change in cursor position in the event handler of the Shown event? You see, in this very case, it would work if you move it into the construction code, without the event handling. But in general case it would be too early. In particular, focusing of something which is not yet shown is impossible.



Also, please look at my code sample to get a good idea how to ask question, how to provide 100% of code. This code is the complete code file, and this is the only one file in the whole application. I got rid of the code generated by the designer, everything, which helped me to create the whole application in this short sample.

If you try to isolate your problem by writing such a small separate application, chances are, you will see the problem more clearly, so you could solve it by yourself. If not, such code is good for posting in your CodeProject question.

—SA


虽然我的学识渊博的同事SAK对RichTextBox的解剖结构给予了极大的了解,引用了他自己头脑中的古代资料(恍惚状态的化石残余物?),以及他所引导的古人的智慧(没有人曾经看着马的嘴巴实际观察马的牙齿......



这只不起眼的跳蚤敢于实际进行实验验证他假设OP有一些与他们 Text插入RichTextBox的特定方式无关的特殊问题。



放三个RichTextBox在窗体上,并在Form_Load事件或Form_Shown EventHandler中,或在您不喜欢的任何其他地方执行此代码,不会导致编译错误:
While my learned colleague, SAK, has given a magnificent peroration on the anatomy of the RichTextBox, citing ancient sources in his own head (fossil remnants of trance-states ?), and wisdom of the ancients that he channels (none of whom ever "looked in the horse's mouth" to actually observe the horse's teeth) ...

This humble flea dares to actually perform an experiment to verify his assumption that the OP has some kind of unusual problem unrelated to the particular way they have inserted Text into a RichTextBox.

Put three RichTextBoxes on a Form, and execute this code in the Form_Load Event, or Form_Shown EventHandler, or anywhere else you please that won't cause a compile error:
private void Form1_Load(object sender, EventArgs e)
{
    this.richTextBox1.Text = "#include \"stdio.h\""
    + Environment.NewLine + "#include \"conio.h\""
    + Environment.NewLine + "int main()"
    + Environment.NewLine + "{"
    + Environment.NewLine + "\t"
    + Environment.NewLine + "\treturn 0;"
    + Environment.NewLine + "}";
    
    this.richTextBox2.Text = "#include \"stdio.h\""
    + "\r" + "#include \"conio.h\""
    + "\r" + "int main()"
    + "\r" + "{"
    + "\r" + "\t"
    + "\r" + "\treturn 0;"
    + "\r" + "}";
    
    this.richTextBox3.Text = "#include \"stdio.h\"\n#include \"conio.h\"\nint main()\n{\n\t\n\treturn 0;\n}";
    
    string t1 = richTextBox1.Text;
    string t2 = richTextBox2.Text;
    string t3 = richTextBox3.Text;
    
    bool sameString = true;
    
    if (t1.Length != t2.Length || t1.Length != t3.Length || t2.Length != t3.Length)
    {
        sameString = false;
    }
    else
    {
    
    for (int i = 0; i < richTextBox1.Text.Length; i++)
    {
        if (t1[i] != t2[i] || t1[i] != t3[i] || t2[i] != t3[i])
        {
            sameString = false;
            break;
        }
    }

    Console.WriteLine("strings are the same: " + sameString.ToString());
}

在输出窗口中观察结果,并自行决定将这三种方法插入到RichTextBox中是否有任何区别。

Observe the result in the 'Output Window, and decide for yourself if there is any difference in these three ways of inserting Text into a RichTextBox.