在winforms richtextbox中对行进行排序,保留RTF格式

时间:2014-03-30 09:20:53

标签: c# winforms sorting richtextbox rtf

有没有办法在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;
    }

2 个答案:

答案 0 :(得分:0)

RichTextBox有一个属性Rtf,可以保留RTF格式。

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

答案 1 :(得分:0)

这是一个代码片段,如果文件既没有嵌入图像也没有嵌入表格,似乎可以正常工作..

它使用两个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&amp; d并没有为严肃的生产做好准备;但它看起来像一个开始。

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