2009-02-12 66 views
1

我使用FormattedText來渲染文本,但似乎有任何方法對呈現的輸出執行每個字符點擊測試。它是隻讀的,所以我基本上只需要選擇,不需要編輯。什麼是對FormattedText執行命中測試的好方法?

我會用RichTextBox或類似的,但我需要根據嵌入在文本本身的控制代碼輸出文本,所以它們不總是嵌套,這使得構建正確的內聯元素非常複雜。我對這個解決方案的表現也有點擔心;我有大量的線條,經常會附加新的線條。

我已經看過GlyphRun,看起來我可以從它或相關的類獲得命中測試,但我會重新實現很多功能,並且似乎應該有一個更簡單的方法...

有誰知道一個很好的實現方法嗎?

回答

3

最好的方法是設計一個好的數據結構來存儲你的文本,並且也考慮命中測試。一個例子可能是將文本分成塊(根據你需要的文字,行或段落)。然後每個這樣的塊應該有一個邊界框,這個邊界框應該在任何格式化操作中重新計算。還要考慮設計中的插入符號位置。

一旦你有了這樣的設備,它就變得非常容易進行命中測試,只需使用邊界框即可。它還將有助於後續操作,如突出顯示文本的特定部分。

+0

FormattedText已經允許我獲取文本範圍的框,但我需要實際的選擇;所以我可能需要每個字符框,這很快就會變得混亂。這是一個可能的解決方案,但不是一個很好的解決方案...... – Eric 2009-02-12 05:05:23

+0

有一個飛重或其他設計模式可以解決類似的問題(單個字符的bbox)。你能查看關於設計模式的Gamma書嗎?它在那裏。 – Sesh 2009-02-12 05:14:37

1

完全同意Sesh--最簡單的方法是,如果不重新實現FormattedText的全部功能,將會通過將要測試的單個項目分割成自己的控件/內聯。

考慮使用TextBlock並添加每個單詞作爲它自己的Inline(或),然後綁定到內聯的IsMouseDirectlyOver屬性,我們將代理添加到MouseEnter & MouseLeave事件中。

如果您想對實際字形進行像素級命中測試(即鼠標正好在這個'i'的圓點中),那麼您需要使用GlyphRuns並對字形進行手動命中測試(閱讀:辛勤工作)。

+0

或者只是使用字形生成整個行的邊界框......點擊測試。 bewmdone。 – 2014-06-05 22:03:07

4

您可以從FormattedText對象中獲取每個字符的幾何圖形,並使用每個字符的邊界進行擊中測試。

var geometry = (GeometryGroup)((GeometryGroup)text.BuildGeometry(new Point(0, 0))).Children[0]; 
foreach (var c in geometry.Children) 
{ 
    if (c.Bounds.Contains(point)) 
    return index; 
    index++; 
} 

在OnRender中,您可以渲染這些幾何對象而不是格式化文本。

1

我非常遲到了 - 如果當事人沒有結束,你不需要實際的字符的幾何形狀,我發現這樣的事情有用:

for (int i = 0; i < FormattedText.Text.Length; i++) 
{ 
      characterHighlightGeometry = FormattedText.BuildHighlightGeometry(new Point(), i, 1); 
      CharacterHighlightGeometries.Children.Add(characterHighlightGeometry); 
} 

BuildGeometry()只包括字符的實際路徑幾何。 BuildHighlightGeometry()生成的所有字符的外部邊界 - 包括 空間,所以一個索引的空間可以由位於:

foreach (var c in CharacterHighlightGeometries.Children) 
     { 
      if (c.Bounds.Contains(centerpoint)) 
      { 
       q = c; 
       cpos = index; 
       break; 
      } 
      index++; 
     } 

希望這有助於。

相關問題