如何在不在RichTextBox中进行选择的情况下恢复插入位置或更改文本颜色

时间:2014-08-12 20:46:09

标签: c# winforms visual-studio-2013 richtextbox

这对我的许多应用程序都是一个问题,我不知道为什么Windows没有这方面的优雅解决方案。

我在VS2013的.Net 4.5中使用Winforms

例如,我想更改多行RichTextBox中一行文本的颜色。

为此,我需要使用类似

的设置来设置选择
rtb.Select(rtb.GetFirstCharIndexFromLine(r), str.Length);

然后,我会使用

设置颜色
rtb.SelectionColor = Color.Red;

大概是,用

取消选择
rtb.DeselectAll();

现在问题是光标/插入符号已移回到行的开头

我尝试通过保存以前的Caret Position来解决它,

rtb.CaretPosition

但是,CaretPosition不是RichTextBox的一种方法,而且在网上到处都是这是每个人使用的主要方法。

我尝试将PresentationFramework添加到我的参考文献中,并添加了我的代码

using System.Windows.Framework;

正如此处所示:http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.caretposition(v=vs.110).aspx

但我仍然没有看到CaretPosition属性,只看到了ScrollToCaret()方法。

我的两个问题是:

  1. 如何在RichTextBox中获取CaretPosition属性?

  2. 如何在不使用选择和影响插入位置的情况下更改文本颜色,必须编写复杂的逻辑以便为用户恢复。

  3. 我的应用程序检查序列号,每行一个,如果它们与格式不匹配则突出显示为红色,如下所示。

    private void rtb_TextChanged(object sender, EventArgs e)
        {
            string pattern = @"[A-Z]{2}[A-Z, 0-9]{2}\d{4}";
            Regex rgx = new Regex(pattern, RegexOptions.IgnoreCase);
    
            TextReader read = new System.IO.StringReader(rtb.Text);
            SerialNumbers.Clear();
            int selectStart = 0;
    
            for (int r = 0; r < rtb.Lines.Length; r++)
            {
                string str = read.ReadLine();
    
                if (str != null)
                {
    
                    selectStart += str.Length;
                    MatchCollection matches = rgx.Matches(str);
                    if (matches.Count == 1)
                    {
                        SerialNumbers.Add(str);
                    }
                    else
                    {
                        rtb.Select(rtb.GetFirstCharIndexFromLine(r), str.Length);
                        rtb.SelectionColor = Color.Red;
                        rtb.DeselectAll();
                    }
    
                }
            }
         }
    

2 个答案:

答案 0 :(得分:1)

你应该使用SelectionCaret(作为评论中提到的@Mangist),因为你使用的是WinForms而不是WPF。您引用的MSDN文章仅适用于WPF,这与WinForms非常不同。

作为示例,我使用以下内容轻松地从WinForms应用程序中的任何位置登录到富文本框:

public static void Log(string text, ref RichTextBox rtbLogBox) {
    //
    if (text == null) return;

    var timestamp = DateTime.Now.ToLongTimeString();
    var logtext = string.Format("{0}    -   {1}\r\n\r\n", timestamp, text);
    if (rtbLogBox.InvokeRequired) {
        var logBox = rtbLogBox;
        logBox.Invoke(new MethodInvoker(delegate {
            logBox.AppendText(logtext);
            logBox.Update();
            logBox.SelectionStart = logBox.Text.Length;
            logBox.ScrollToCaret();
        }));
    } else {
        rtbLogBox.AppendText(logtext);
        rtbLogBox.Update();
        rtbLogBox.SelectionStart = rtbLogBox.Text.Length;
        rtbLogBox.ScrollToCaret();
    }
}

注意在将ScrollToCaret()设置为富文本框中文本的长度后,如何调用SelectionStart。这解决了“问题”的问题。 AppendText添加文字后没有滚动到底部。

在您的情况下,您只需要在使用突出显示格式化文本之前保存SelectionStart值,然后在完成后将其恢复。

答案 1 :(得分:1)

通过保存SelectionStart位置

来修复它
                int selectionStart = SNbox.SelectionStart;

                SNbox.Select(SNbox.GetFirstCharIndexFromLine(r), str.Length);
                SNbox.SelectionColor = Color.Red;
                SNbox.DeselectAll();

                SNbox.SelectionStart = selectionStart;
                SNbox.SelectionLength = 0;