我想选择richtextbox中有蓝色的所有单词。我怎样才能做到这一点? 在richtextbox中,有一些蓝色关键字。我希望将所有这些关键字作为一个集合。
答案 0 :(得分:1)
通过"选择",我认为你的意思是"找到"。我不相信您可以在RichTextBox中实际选择多个不连续的文本范围。
假设我的理解是正确的,这里有一些经过适度测试的代码,我最近一直在努力。让我知道它对你有用。
请注意,RichTextBox
中的所有文字内容实际上都存储在FlowDocument
中,可通过Document
属性访问。要遍历字符串,您需要在TextElement
中遍历FlowDocument
类的层次结构。下面这样做,返回每个字符串和表示层次结构的堆栈,可能由选择器方法转换:
public static IEnumerable<KeyValuePair<Stack<T>, string>> WalkTextElements<T>(FlowDocument doc, Func<DependencyObject, Stack<T>, T> selector)
{
// Inspiration: http://www.bryanewert.net/journal/2010/5/26/how-to-explore-the-contents-of-a-flowdocument.html
if (doc != null)
{
var stack = new Stack<T>();
// Start with a TextPointer to FlowDocument.ContentStart
TextPointer t = doc.ContentStart;
// Keep a TextPointer for FlowDocument.ContentEnd handy, so we know when we're done.
TextPointer e = doc.ContentEnd;
// Keep going until the TextPointer is equal to or greater than ContentEnd.
while ((t != null) && (t.CompareTo(e) < 0))
{
// Identify the type of content immediately adjacent to the text pointer.
TextPointerContext context = t.GetPointerContext(LogicalDirection.Forward);
// ElementStart is an "opening tag" which defines the structure of the document, e.g. a paragraph declaration.
if (context == TextPointerContext.ElementStart)
{
stack.Push(selector(t.Parent, stack));
}
// An EmbeddedElement, e.g. a UIContainer.
else if (context == TextPointerContext.EmbeddedElement)
{
; // Do nothing.
}
// The document's text content.
else if (context == TextPointerContext.Text)
{
stack.Push(selector(t.Parent, stack));
yield return new KeyValuePair<Stack<T>, string>(stack, t.GetTextInRun(LogicalDirection.Forward));
stack.Pop();
}
// ElementEnd is a "closing tag".
else if (context == TextPointerContext.ElementEnd)
{
stack.Pop();
}
else
{
throw new System.Exception("Unhandled TextPointerContext " + context.ToString());
}
// Advance to the next ContentElement in the FlowDocument.
t = t.GetNextContextPosition(LogicalDirection.Forward);
}
}
}
有了这个,我们可以枚举显式重写背景颜色的字符串:
/// <summary>
/// Enumerate all the strings in a given flow document that are have an explicit background color.
/// </summary>
/// <param name="doc"></param>
/// <param name="includeFlowDocumentColor">true to consider overrides on the entire FlowDocument itself, else false.</param>
/// <returns></returns>
public static IEnumerable<KeyValuePair<Brush, string>> WalkBackgroundColoredTexts(FlowDocument doc, bool includeFlowDocumentColor)
{
foreach (var pair in WalkTextElements<Brush>(doc, (d, s) => SelectTextBackgroundBrush(d, s, includeFlowDocumentColor)))
{
var brush = pair.Key.Peek();
if (brush != null)
{
yield return new KeyValuePair<Brush, string>(brush, pair.Value);
}
}
}
static Brush SelectTextBackgroundBrush(DependencyObject element, Stack<Brush> brushes, bool includeFlowDocumentColor)
{
//http://blogs.msdn.com/b/prajakta/archive/2006/10/11/flowdocument-content-model.aspx
//http://msdn.microsoft.com/en-us/library/aa970786%28v=vs.110%29.aspx
var textElement = element as TextElement;
if (textElement != null)
{
var brush = textElement.Background;
if (brush != null)
return brush;
return PeekOrDefault(brushes);
}
var tableColumn = element as TableColumn;
if (tableColumn != null)
{
var brush = tableColumn.Background;
if (brush != null)
return brush;
return PeekOrDefault(brushes);
}
if (includeFlowDocumentColor)
{
var doc = element as FlowDocument;
if (doc != null)
{
var brush = doc.Background;
if (brush != null)
return brush;
return PeekOrDefault(brushes);
}
}
return null;
}
static T PeekOrDefault<T>(Stack<T> stack)
{
return (stack.Count == 0 ? default(T) : stack.Peek());
}
您可能希望忽略流文档本身设置的背景颜色,并仅获取具有背景颜色集的特定文本运行,这就是我添加参数的原因。
鉴于字符串,您可能仍需要将它们标记为单词。