在保存RTF格式的winforms richtextbox中排序行

本文关键字:richtextbox 排序 winforms 保存 RTF 格式 | 更新日期: 2023-09-27 17:54:53

是否有办法在winforms richtextbox中保留RTF格式?

var lines = edit.Lines.OrderBy(s => s);
edit.Lines = lines.ToArray();

可以很好地完成这项工作,但是,很明显,失去了任何RTF格式。

我稍微改变了TaW的代码片段:1. 添加"unique"可能会破坏第一行的格式2. 除了"'par"标签,还有"'pard"

下面是一个片段(再次感谢TaW!):

private void cmdSort_Click(object sender, EventArgs e)
    {
        const string PARD = "''pard";
        var pard = Guid.NewGuid().ToString();
        var pos1 = edit.Rtf.IndexOf(PARD, StringComparison.Ordinal) + PARD.Length;
        if (pos1 < 0) return;
        var header = edit.Rtf.Substring(0, pos1);
        var body = edit.Rtf.Substring(pos1);
        body = body.Replace("''pard", pard);
        var lines = body.Split(new[] { "''par" }, StringSplitOptions.None);
        var lastFormat = "";
        var sb = new StringBuilder();
        var rtfLines = new SortedList<string, string>();
        foreach (var line in lines)
        {
            var ln = line.Replace(pard, "''pard");
            var temp = ln.Replace("'r'n", "").Trim();
            if (temp.Length > 0 && temp[0] != '''')
            {
                rtfLines.Add(temp.Trim(), lastFormat + " " + ln);
            }
            else
            {
                var pos2 = temp.IndexOf(' ');
                if (pos2 < 0)
                {
                    rtfLines.Add(temp.Trim(), ln);
                }
                else
                {
                    rtfLines.Add(temp.Substring(pos2).Trim(), ln);
                    lastFormat = temp.Substring(0, pos2);
                }
            }
        }
        foreach (var key in rtfLines.Keys.Where(key => key != "}"))
        {
            sb.Append(rtfLines[key] + "''par");
        }
        edit.Rtf = header + sb;
    }

在保存RTF格式的winforms richtextbox中排序行

如果文件中既没有嵌入图像也没有嵌入表,那么这里的代码片段似乎可以工作。

它使用两个RTF框。在我的测试中,它们排序正常,并保持所有格式完整。

    private void button4_Click(object sender, EventArgs e)
    {
        string unique = Guid.NewGuid().ToString() ; 
        richTextBox1.SelectionStart = 0;
        richTextBox1.SelectionLength = 0;
        richTextBox1.SelectedText = unique;
        int pos1 = richTextBox1.Rtf.IndexOf(unique);
        if (pos1 >= 0)
        {
            string header = richTextBox1.Rtf.Substring(0, pos1);
            string header1 = "";
            string header2 = "";
            int pos0 = header.LastIndexOf('}') + 1;
            if (pos0 > 1) { header1 = header.Substring(0, pos0); header2 = header.Substring(pos0); }
            // after the header comes a string of formats to start the document
            string[] formats = header2.Split('''');
            string firstFormat = "";
            string lastFormat = "";
            // we extract a few important character formats (bold, italic, underline, font, color)
            // to keep with the first line which will be sorted away
            // the lastFormat variable holds the last formatting encountered
            // so we can add it to all lines without formatting
            // (and of course we are really talking about paragraphs)
            foreach (string fmt in formats)  
                if (fmt[0]=='b' ||  ("cfiu".IndexOf(fmt[0]) >= 0 && fmt.Substring(0,2)!="uc") ) 
                      lastFormat += "''" + fmt; else firstFormat += "''" + fmt;
            // add the rest to the header
            header = header1 + firstFormat;
            // now we remove our marker from the body and split it into paragraphs
            string body = richTextBox1.Rtf.Substring(pos1);
            string[] lines = body.Replace(unique, "").Split(new string[] { "''par" }, StringSplitOptions.None);
            StringBuilder sb = new StringBuilder();
            // the soteredlist will contain the unformatted text as key and the formatted one as valaue
            SortedList<string, string> rtfLines = new SortedList<string, string>();
            foreach (string line in lines)
                {
                    // cleanup
                    string line_ = line.Replace("'r'n", "").Trim();
                    if (line_[0] != '''' ) rtfLines.Add(line_, lastFormat + " " + line);
                    else
                    {
                        int pos2 = line_.IndexOf(' ');
                        if (pos2 < 0) rtfLines.Add(line_, line);
                        else
                        {
                            rtfLines.Add(line_.Substring(pos2).Trim(), line);
                            lastFormat = line_.Substring(0, pos2);
                        }
                    }
                }
            foreach (string key in rtfLines.Keys) if (key != "}") sb.Append(rtfLines[key] + "''par");
            richTextBox2.Rtf = header + sb.ToString();
        }

当然这是真的q&d,还没有准备好正式生产;但这看起来是个开始。

EDIT 2:我修改了代码以修复第一行格式的错误,并添加了一些注释。这应该工作得更好,但仍然是一个必须适应实际输入文件的hack .

RichTextBox有一个属性Rtf,将保持Rtf格式。

[BrowsableAttribute(false)]
public string Rtf { get; set; }