簡體   English   中英

在Winforms RichTextBox中對行進行排序以保留RTF格式

[英]Sorting lines in winforms richtextbox preserving RTF formatting

有什么辦法可以在保留RTF格式的winforms richtextbox中對行進行排序?

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

做得很好,但是很明顯,它失去了任何RTF格式。

我稍微改變了TaW的代碼段:1.添加“唯一”可能會破壞第一行的格式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;
    }

RichTextBox具有Rtf屬性,該屬性將保持RTF格式。

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

如果文件既沒有圖像也沒有表嵌入,那么這是一個似乎有效的代碼片段。

它使用兩個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();
        }

當然,這確實是問答環節,還沒有准備好進行大批量生產。 但這似乎是一個開始。

編輯2 :我更改了代碼以修復第一行格式的錯誤,並添加了一些注釋。 這應該工作得更好,但仍然是必須適應實際輸入文件的技巧。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM