簡體   English   中英

如何使用現有內容格式化RichTextBox

[英]How to format a RichTextBox with existing contents

我從Web API獲取數據,返回文本和格式信息。 格式化數據僅包括格式類型(粗體,斜體等)以及格式化的范圍。 這個問題的主要問題是,兩個范圍可以“碰撞”(例如,單詞的前3個字符是粗體和斜體,但最后3個字符只是斜體)。 響應示例

{
  "text" : "This is an example text",
  "inlineStyles" : [
    {
      "offsetFromStart" : 5,
      "length" : 10,
      "type" : "bold"
    }
    {
      "offsetFromStart" : 10,
      "length" : 10,
      "type" : "italic"
    }
  ]
}

我已經嘗試使用簡單的TextBlock執行此操作並失敗。 我也嘗試使用RichTextBox,但是當我添加了Span時,我無法將其插入原始位置。 我還試圖用自己的跨度或運行格式化每個角色,但這將是非常丑陋的,通常只是一個糟糕的解決方案。 (我主要擔心的是速度..)

var tb = new RichTextBox();
var para = new Paragraph();
para.Inlines.Add("This is an example text") // Text parsed from the response

var startingPointer1 = para.ContentStart.GetPositionAtOffset(5);
var sp1 = new Span(startingPointer1, startingPointer1.GetPositionAtOffset(10));
sp1.FontWeight = FontWeights.Bold;

var startingPointer2 = para.ContentStart.GetPositionAtOffset(10);
var sp2 = new Span(startingPointer2 , startingPointer2 .GetPositionAtOffset(10));
sp2.FontStyle= FontStyles.Italic;

para.Inlines.Add(sp1);
para.Inlines.Add(sp2);
tb.Document.Blocks.Add(para);

這段代碼將它追加到最后,當組合多個內聯元素時,就像我的例子中一樣,它根本不起作用(因為第一個問題。)

示例結果: 示例圖片

我不認為你可以像這樣重疊運行/跨度,你必須找到文本中的所有斷點並分別格式化每個文本范圍。 它類似於HTML,其中

<bold>some<italic> bold italic</bold> and other </italic> text.

無效。 在你的情況下,你將從(5,10)粗體,(11,15)等粗體。

找到某種Range類並使用方法來組合范圍,拆分,查找重疊等可能很有用。前段時間我開始使用

編輯:我不知道如何實現所有這些(上次我做了類似的事情差不多10年前),但你可以嘗試這樣的事情:

  1. 創建一個List<Range<int>> 最初它包含一個Range(0,文本長度)。
  2. 加載第一個樣式,創建一個帶有開始/結束偏移的新范圍。 重疊(或任何適當的方法)此范圍與列表中的范圍。 這應該給你3個范圍,比如(0, start of style), (start of style, end of style), (end of style, end of text) 從列表中刪除舊范圍並添加新范圍。
  3. 加載下一個,找到重疊,列表中的范圍,刪除重疊的那些並添加新范圍。
  4. 這應該給你一個非重疊范​​圍的列表。
  5. 現在,對於風格。 您可以創建一種樣式表類。 此類可以使用System.Windows定義的FontWeights, FontStyles和其他枚舉。 修改列表,使其包含,例如, List<Tuple<int, Stylesheet>> 要計算重疊,只需使用元組中的第一個參數。
  6. 在從列表中刪除舊范圍之前,請合並樣式。
  7. 這應該為您提供具有適當樣式的非重疊區域列表。 創建TextRange ,應用樣式

其他可能有用的想法:

  1. 再次,創建一個樣式表。 最初它應該是正常的重量,正常的樣式,默認的字體大小等。
  2. 從輸入中找到下一個偏移量(第一個大於當前值的偏移量),創建TextRange並應用樣式。
  3. 從輸入中查找下一個偏移量,修改當前(且僅限)樣式並應用。

如果我沒記錯的話,在文本中插入樣式定義也會計為字符,因此在最終文本中插入樣式標記時可能需要調整偏移量。 另外,我相信只使用TextBlock是可行的。

正如我所說,我不知道這是否如所述,但這可能會給你和想法。

我目前的解決方案是逐個瀏覽每個字符並掃描范圍,檢測當前字符是否在其中任何字符中,然后為字符分配跨度。 這根本理想,但它完成了工作。 我稍后會嘗試為此實現一個實際的算法。 在此之前,如果您有任何可以提供幫助的信息,請發表評論。

如果有人需要我當前實現的示例代碼,我很樂意與您分享。 (盡管它根本沒有效率)

暫無
暫無

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

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