C# 在WPF中突出显示richtextbox中的关键字
我正在制作一个程序,需要浏览一段文字,找出某个关键字出现的次数。它还必须突出文本中的每个关键词 我已经设法使他界面,它现在可以跟踪多少次这个词出现,但我真的陷入了如何突出显示关键字出现的地方。我将在下面发布我的代码,任何关于如何在richtextbox中搜索和突出显示文本的帮助都将不胜感激。由于这是在WPF中,显然richtextbox.find()不可用C# 在WPF中突出显示richtextbox中的关键字,c#,wpf,string,text,highlighting,C#,Wpf,String,Text,Highlighting,我正在制作一个程序,需要浏览一段文字,找出某个关键字出现的次数。它还必须突出文本中的每个关键词 我已经设法使他界面,它现在可以跟踪多少次这个词出现,但我真的陷入了如何突出显示关键字出现的地方。我将在下面发布我的代码,任何关于如何在richtextbox中搜索和突出显示文本的帮助都将不胜感激。由于这是在WPF中,显然richtextbox.find()不可用 class TextAnalyser { public int FindNumberOfOccurances(List<str
class TextAnalyser
{
public int FindNumberOfOccurances(List<string> keywords, string email)
{
int occurances = 0;
foreach (string keyword in keywords)
{
occurances += email.ToUpper().Split(new string[] { keyword.ToUpper() }, StringSplitOptions.None).Count() - 1;
}
return occurances;
}
public void TurnTextRed(List<string> keywords, string email, RichTextBox TextBox)
{
foreach(string keyword in keywords)
{
}
}
public List<string> ConvertTextToList(string text)
{
char[] splitChars = {};
string[] ArrayText = text.Split( splitChars, StringSplitOptions.RemoveEmptyEntries);
return ArrayText.ToList<string>();
}
public string GetStringFromTextBox(RichTextBox TextBox)
{
var textRange = new TextRange(
TextBox.Document.ContentStart,
TextBox.Document.ContentEnd
);
return textRange.Text;
}
}
下面是用于获取richtextbox文档中所有word的方法
public static IEnumerable<TextRange> GetAllWordRanges(FlowDocument document)
{
string pattern = @"[^\W\d](\w|[-']{1,2}(?=\w))*";
TextPointer pointer = document.ContentStart;
while (pointer != null)
{
if (pointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
{
string textRun = pointer.GetTextInRun(LogicalDirection.Forward);
MatchCollection matches = Regex.Matches(textRun, pattern);
foreach (Match match in matches)
{
int startIndex = match.Index;
int length = match.Length;
TextPointer start = pointer.GetPositionAtOffset(startIndex);
TextPointer end = start.GetPositionAtOffset(length);
yield return new TextRange(start, end);
}
}
pointer = pointer.GetNextContextPosition(LogicalDirection.Forward);
}
}
公共静态IEnumerable GetAllWordRanges(FlowDocument文档)
{
字符串模式=@“[^\W\d](\W|[-']{1,2}(?=\W))*”;
text指针指针=document.ContentStart;
while(指针!=null)
{
if(pointer.GetPointerContext(LogicalDirection.Forward)=TextPointerContext.Text)
{
字符串textRun=pointer.gettRun(LogicalDirection.Forward);
MatchCollection matches=Regex.matches(textRun,pattern);
foreach(匹配中的匹配)
{
int startIndex=match.Index;
int length=match.length;
TextPointer start=pointer.GetPositionAtOffset(startIndex);
TextPointer end=start.GetPositionAtOffset(长度);
返回新文本范围(开始、结束);
}
}
指针=指针.GetNextContextPosition(LogicalDirection.Forward);
}
}
您可以更改用于拆分单词的模式
最后,容易突出你的话
IEnumerable<TextRange> wordRanges = GetAllWordRanges(RichTextBox.Document);
foreach (TextRange wordRange in wordRanges)
{
if (wordRange.Text == "keyword")
{
wordRange.ApplyPropertyValue(TextElement.ForegroundProperty, Brushes.Red);
}
}
IEnumerable wordRanges=GetAllWordRanges(RichTextBox.Document);
foreach(文本范围wordRange中的文本范围wordRange)
{
if(wordRange.Text==“关键字”)
{
wordRange.ApplyPropertyValue(TextElement.ForegroundProperty,Bruss.Red);
}
}
遇到这种需求,无法找到任何合适的解决方案。(使用文本框进行绑定、动态突出显示、多次点击和颜色等)这显然可以扩展以满足您的需要。这引用了两个扩展方法,它们从UIElement的装饰器层添加/删除指定类型T的装饰器
public class HighlightRule
{
public SolidColorBrush Brush { get; set; }
public string MatchText { get; set; }
public HighlightRule(SolidColorBrush solidColorBrush, string matchText)
{
Brush = solidColorBrush;
MatchText = matchText;
}
public HighlightRule(Color color, string matchText)
{
Brush = new SolidColorBrush(color);
MatchText = matchText;
}
public HighlightRule()
{
MatchText = null;
Brush = Brushes.Black;
}
}
public class HighlightTextBox : TextBox
{
public List<HighlightRule> HighlightRules
{
get { return ( List<HighlightRule>)GetValue(HighlightRulesProperty); }
set { SetValue(HighlightRulesProperty, value); }
}
// Using a DependencyProperty as the backing store for HighlightRules. This enables animation, styling, binding, etc...
public static readonly DependencyProperty HighlightRulesProperty =
DependencyProperty.Register("HighlightRules", typeof(List<HighlightRule>), typeof(HighlightTextBox), new FrameworkPropertyMetadata(new List<HighlightRule>(), new PropertyChangedCallback(HighlightRulesChanged)));
private static void HighlightRulesChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
HighlightTextBox tb = (HighlightTextBox)sender;
tb.ApplyHighlights();
}
public HighlightTextBox() : base()
{
this.Loaded += HighlightTextBox_Loaded;
}
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
ApplyHighlights();
}
private void HighlightTextBox_Loaded(object sender, RoutedEventArgs e)
{
ApplyHighlights();
}
static HighlightTextBox()
{
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
public void ApplyHighlights()
{
this.TryRemoveAdorner<GenericAdorner>();
foreach(HighlightRule rule in HighlightRules)
{
if (!string.IsNullOrEmpty(rule.MatchText) && !string.IsNullOrEmpty(Text) &&
Text.ToLower().Contains(rule.MatchText.ToLower()))
{
if (base.ActualHeight != 0 && base.ActualWidth != 0)
{
int indexOf = 0;
do
{
indexOf = Text.IndexOf(rule.MatchText, indexOf);
if (indexOf == -1) break;
Rect rect = base.GetRectFromCharacterIndex(indexOf);
Rect backRect = base.GetRectFromCharacterIndex(indexOf + rule.MatchText.Length - 1, true);
this.TryAddAdorner<GenericAdorner>(new GenericAdorner(this, new Rectangle()
{ Height = rect.Height, Width = backRect.X - rect.X, Fill = rule.Brush, Opacity = 0.5 }));
indexOf++;
} while (true);
}
}
}
}
}
公共类高亮规则
{
公共SolidColorBrush笔刷{get;set;}
公共字符串匹配文本{get;set;}
公共高亮规则(SolidColorBrush SolidColorBrush,字符串匹配文本)
{
画笔=纯色画笔;
匹配文本=匹配文本;
}
公共高亮规则(颜色、字符串匹配文本)
{
笔刷=新的SolidColorBrush(颜色);
匹配文本=匹配文本;
}
公共交通灯规则()
{
MatchText=null;
画笔=画笔。黑色;
}
}
公共类HighlightTextBox:TextBox
{
公共列表高亮规则
{
get{return(List)GetValue(HighlightRulesProperty);}
set{SetValue(HighlightRulesProperty,value);}
}
//使用DependencyProperty作为HighlightRules的后台存储。这将启用动画、样式、绑定等。。。
公共静态只读从属属性HighlightRulesProperty=
DependencyProperty.Register(“HighlightRules”、typeof(List)、typeof(HighlightTextBox)、new FrameworkPropertyMetadata(new List()、new PropertyChangedCallback(HighlightRulesChanged));
私有静态无效高亮规则更改(DependencyObject发件人,DependencyPropertyChangedEventArgs e)
{
HighlightTextBox tb=(HighlightTextBox)发送方;
tb.ApplyHighlights();
}
公共HighlightTextBox():base()
{
this.Loaded+=HighlightTextBox\u Loaded;
}
受保护的覆盖void OnTextChanged(textchangedventargs e)
{
base.OnTextChanged(e);
ApplyHighlights();
}
已加载private void HighlightTextBox_(对象发送方,路由目标)
{
ApplyHighlights();
}
静态HighlightTextBox()
{
}
应用程序模板()上的公共重写无效
{
base.OnApplyTemplate();
}
公共无效ApplyHighlights()
{
this.TryRemoveAdorner();
foreach(HighlightRules中的HighlightRule规则)
{
如果(!string.IsNullOrEmpty(rule.MatchText)和&!string.IsNullOrEmpty(Text)&&
Text.ToLower()包含(rule.MatchText.ToLower())
{
如果(base.actualwhite!=0&&base.actualwhith!=0)
{
int indexOf=0;
做
{
indexOf=Text.indexOf(rule.MatchText,indexOf);
如果(indexOf==-1)中断;
Rect Rect=base.GetRectFromCharacterIndex(indexOf);
Rect backRect=base.GetRectFromCharacterIndex(indexOf+rule.MatchText.Length-1,true);
this.TryAddAdorner(新的GenericAdorner(this,新的矩形)()
{Height=rect.Height,Width=backRect.X-rect.X,Fill=rule.Brush,Opacity=0.5});
indexOf++;
}虽然(正确);
}
}
}
}
}
GenericAdorner/Helper方法
public class GenericAdorner : Adorner
{
private readonly UIElement adorner;
private readonly Point point;
public GenericAdorner(UIElement targetElement, UIElement adorner, Point point) : base(targetElement)
{
this.adorner = adorner;
if (adorner != null)
{
AddVisualChild(adorner);
}
this.point = point;
}
protected override int VisualChildrenCount
{
get { return adorner == null ? 0 : 1; }
}
protected override Size ArrangeOverride(Size finalSize)
{
if (adorner != null)
{
adorner.Arrange(new Rect(point, adorner.DesiredSize));
}
return finalSize;
}
protected override Visual GetVisualChild(int index)
{
if (index == 0 && adorner != null)
{
return adorner;
}
return base.GetVisualChild(index);
}
}
public static void TryRemoveAdorner<T>(this UIElement element)
where T:Adorner
{
AdornerLayer layer = AdornerLayer.GetAdornerLayer(element);
if (layer != null)
layer.RemoveAdorners<T>(element);
}
public static void RemoveAdorners<T>(this AdornerLayer layer, UIElement element)
where T : Adorner
{
var adorners = layer.GetAdorners(element);
if (adorners == null) return;
for (int i = adorners.Length -1; i >= 0; i--)
{
if (adorners[i] is T)
layer.Remove(adorners[i]);
}
}
public static void TryAddAdorner<T>(this UIElement element, Adorner adorner)
where T: Adorner
{
AdornerLayer layer = AdornerLayer.GetAdornerLayer(element);
if (layer != null)
try
{
layer.Add(adorner);
}
catch (Exception) { }
}
public static bool HasAdorner<T>(this AdornerLayer layer, UIElement element) where T : Adorner
{
var adorners = layer.GetAdorners(element);
if (adorners == null) return false;
for (int i = adorners.Length - 1; i >= 0; i--)
{
if (adorners[i] is T)
return true;
}
return false;
}
public static void RemoveAdorners(this AdornerLayer layer, UIElement element)
{
var adorners = layer.GetAdorners(element);
if (adorners == null) return;
foreach (Adorner remove in adorners)
layer.Remove(remove);
}
公共类GenericAdorner:Adorner
{
私有只读UIElement装饰器;
私有只读点;
公共GenericAdorner(UIElement目标元素、UIElement装饰器、点):基(目标元素)
{
this.adorner=装饰器;
if(装饰器!=null)
{
AddVisualChild(装饰器);
}
这个点=点;
}
受保护的重写int VisualChildrenCount
{
获取{返回装饰器==null?0:1;}
}
受保护的替代尺寸排列替代(尺寸最终化)
public class GenericAdorner : Adorner
{
private readonly UIElement adorner;
private readonly Point point;
public GenericAdorner(UIElement targetElement, UIElement adorner, Point point) : base(targetElement)
{
this.adorner = adorner;
if (adorner != null)
{
AddVisualChild(adorner);
}
this.point = point;
}
protected override int VisualChildrenCount
{
get { return adorner == null ? 0 : 1; }
}
protected override Size ArrangeOverride(Size finalSize)
{
if (adorner != null)
{
adorner.Arrange(new Rect(point, adorner.DesiredSize));
}
return finalSize;
}
protected override Visual GetVisualChild(int index)
{
if (index == 0 && adorner != null)
{
return adorner;
}
return base.GetVisualChild(index);
}
}
public static void TryRemoveAdorner<T>(this UIElement element)
where T:Adorner
{
AdornerLayer layer = AdornerLayer.GetAdornerLayer(element);
if (layer != null)
layer.RemoveAdorners<T>(element);
}
public static void RemoveAdorners<T>(this AdornerLayer layer, UIElement element)
where T : Adorner
{
var adorners = layer.GetAdorners(element);
if (adorners == null) return;
for (int i = adorners.Length -1; i >= 0; i--)
{
if (adorners[i] is T)
layer.Remove(adorners[i]);
}
}
public static void TryAddAdorner<T>(this UIElement element, Adorner adorner)
where T: Adorner
{
AdornerLayer layer = AdornerLayer.GetAdornerLayer(element);
if (layer != null)
try
{
layer.Add(adorner);
}
catch (Exception) { }
}
public static bool HasAdorner<T>(this AdornerLayer layer, UIElement element) where T : Adorner
{
var adorners = layer.GetAdorners(element);
if (adorners == null) return false;
for (int i = adorners.Length - 1; i >= 0; i--)
{
if (adorners[i] is T)
return true;
}
return false;
}
public static void RemoveAdorners(this AdornerLayer layer, UIElement element)
{
var adorners = layer.GetAdorners(element);
if (adorners == null) return;
foreach (Adorner remove in adorners)
layer.Remove(remove);
}
<local:HighlightTextBox FontFamily="Calibri" Foreground="Blue" FontSize="12" Text="Hello you!! And also hello to you!" TextWrapping="Wrap" Margin="5,3,0,0">
<local:HighlightTextBox.HighlightRules>
<local:HighlightRule Brush="Red" MatchText="you"/>
<local:HighlightRule Brush="Blue" MatchText="also"/>
</local:HighlightTextBox.HighlightRules>
</local:HighlightTextBox>