我在WPF中有一个要求......
感谢任何帮助。我尝试了几种方法,但在上一点失败了。
//代码段
// Xaml文件
<Window x:Class="RichtextBoxhighlight.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:RichtextBoxhighlight"
Title="MainWindow" Height="406" Width="855"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
<src:ContentPlainConverter x:Key="typeConverter" />
<src:TestConvertor x:Key="spaceRem"/>
<Style x:Key="RichTextBoxWithRoundedCorners" TargetType="{x:Type RichTextBox}">
<Style.Resources>
<Style x:Key="{x:Type FlowDocument}" TargetType="{x:Type FlowDocument}">
<Setter Property="OverridesDefaultStyle" Value="true"/>
</Style>
</Style.Resources>
</Style>
</Window.Resources>
<Grid>
<TextBox Margin="114,14,130,255" Name="txtText" />
<Grid>
<ListView Height="241" ItemsSource="{Binding CollRemarks}" HorizontalAlignment="Left" Margin="0,126,0,0" Name="listView1" VerticalAlignment="Top" Width="827" >
<ListView.View >
<GridView >
<GridViewColumn Header="Type" Width="80" DisplayMemberBinding="{Binding Path=type}"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=Operatorid}" Width="70">
<GridViewColumnHeader Tag="CreatedEmployeeId" Content="Operator"/>
</GridViewColumn>
<GridViewColumn Width="710">
<GridViewColumn.CellTemplate>
<DataTemplate>
<src:BindableRichTextBox Document ="{Binding Path=remarks, Converter= {StaticResource typeConverter}}" HighlightPhrase="{Binding ElementName=txtText, Path=Text,Converter={StaticResource spaceRem}}" IsReadOnly="True" Background="Transparent" BorderBrush="Transparent" BorderThickness="0"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
<GridViewColumnHeader Tag="CommentText" Content="Remark" />
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Grid>
</Window>
//BindableRichTextBox class :
namespace RichtextBoxhighlight
{
public class BindableRichTextBox : RichTextBox
{
public static string oldstring;
public static readonly DependencyProperty DocumentProperty =
DependencyProperty.Register("Document", typeof(FlowDocument),
typeof(BindableRichTextBox), new FrameworkPropertyMetadata
(null, new PropertyChangedCallback(OnDocumentChanged)));
public static readonly DependencyProperty HighlightPhraseProperty =
DependencyProperty.Register("HighlightPhrase", typeof(string),
typeof(BindableRichTextBox), new FrameworkPropertyMetadata(String.Empty, FrameworkPropertyMetadataOptions.AffectsRender,
new PropertyChangedCallback(UpdateHighlighting)));
public string HighlightPhrase
{
get { return (string)GetValue(HighlightPhraseProperty); }
set { SetValue(HighlightPhraseProperty, value); }
}
private static void UpdateHighlighting(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
//invoked on text box search
ApplyHighlight(d as BindableRichTextBox);
ApplyAllHighlight(d as BindableRichTextBox);
}
// Gets or sets the Document of RichtextBox
public new FlowDocument Document
{
get
{
return (FlowDocument)this.GetValue(DocumentProperty);
}
set
{
this.SetValue(DocumentProperty, value);
}
}
// Method invoked on documnet formation.
public static void OnDocumentChanged(DependencyObject obj,
DependencyPropertyChangedEventArgs args)
{
try
{
RichTextBox rtb = (RichTextBox)obj;
// ApplyHighlight(rtb as BindableRichTextBox);
rtb.Document = (FlowDocument)args.NewValue;
ApplyAllHighlight(rtb as BindableRichTextBox);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// Implementation logic for Text Changed search highlight
/// </summary>
private static void ApplyHighlight(BindableRichTextBox tb)
{
try
{
if (tb != null && tb.Document != null)
{
string highlightPhrase = tb.HighlightPhrase;
// Frame the highlight word to skip them from getting highlighted by searchtext
string highlightWords = "(";
for (int i = 0; i < MainWindow.Highlightwords.Count; i++)
{
highlightWords += MainWindow.Highlightwords[i];
if (i != MainWindow.Highlightwords.Count - 1)
highlightWords += "|";
}
highlightWords += ")";
var start = tb.Document.ContentStart;
TextRange range = new TextRange(start, tb.Document.ContentEnd);
range.ClearAllProperties();
Regex ignore = new Regex(highlightWords, RegexOptions.Compiled | RegexOptions.IgnoreCase);
string Text = range.Text;
int index_match = 0;
if (highlightPhrase != string.Empty && highlightPhrase != null)
{
while (start != null && start.CompareTo(tb.Document.ContentEnd) < 0)
{
// Comparison to skip the key words in the column to be highlighted
if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
{
index_match = Text.IndexOf(highlightPhrase, StringComparison.OrdinalIgnoreCase);
if (index_match >= 0)
{
//Ignore all Keyword highlight by incrementing start and moving to next match
MatchCollection matches = ignore.Matches(start.GetTextInRun(LogicalDirection.Forward));
if (matches != null)
{
for (int i = 0; i < matches.Count; i++)
{
if ((index_match >= matches[i].Index && index_match <= matches[i].Index + matches[i].Length))
{
start = start.GetPositionAtOffset(matches[i].Index + matches[i].Length, LogicalDirection.Forward);
Text = new TextRange(start.GetInsertionPosition(LogicalDirection.Forward), start.DocumentEnd).Text;
//Highlight the search text if part before keyword
if (highlightPhrase.Length > matches[i].Length)
{
var textrange = new TextRange(start.GetPositionAtOffset(0, LogicalDirection.Forward), start.GetPositionAtOffset(highlightPhrase.Length - matches[i].Length, LogicalDirection.Backward));
textrange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.Green));
}
if (start != null && start.CompareTo(tb.Document.ContentEnd) < 0)
{
index_match = Text.IndexOf(highlightPhrase, StringComparison.OrdinalIgnoreCase);
if (index_match >= 0)
{
matches = ignore.Matches(start.GetTextInRun(LogicalDirection.Forward));
if (matches != null && matches.Count > 0)
i--;
}
else
break;
}
}
else if ((highlightPhrase.Length - 1 >= matches[i].Index && highlightPhrase.Length + index_match <= matches[i].Index + matches[i].Length))
{
//Highlight the search text if part after keyword
var textrange = new TextRange(start.GetPositionAtOffset(index_match, LogicalDirection.Forward), start.GetPositionAtOffset(matches[i].Index, LogicalDirection.Backward));
textrange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.Green));
start = start.GetPositionAtOffset(matches[i].Index + matches[i].Length, LogicalDirection.Forward);
Text = new TextRange(start.GetInsertionPosition(LogicalDirection.Forward), start.DocumentEnd).Text;
if (start != null && start.CompareTo(tb.Document.ContentEnd) < 0)
{
index_match = Text.IndexOf(highlightPhrase, StringComparison.OrdinalIgnoreCase);
if (index_match >= 0)
{
matches = ignore.Matches(start.GetTextInRun(LogicalDirection.Forward));
if (matches != null && matches.Count > 0)
i--;
}
else
break;
}
}
}
}
if (index_match >= 0 && start != null && (start.CompareTo(tb.Document.ContentEnd) < 0))
{
//Highlight the search text typed if not part of Keywords
var textrange = new TextRange(start.GetPositionAtOffset(index_match, LogicalDirection.Forward), start.GetPositionAtOffset(index_match + highlightPhrase.Length, LogicalDirection.Backward));
textrange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.Green));
start = textrange.End;
Text = new TextRange(textrange.End, start.DocumentEnd).Text;
}
}
else
break;
}
if (start != null && start.CompareTo(tb.Document.ContentEnd) < 0)
start = start.GetNextContextPosition(LogicalDirection.Forward);
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
/// <summary>
/// Implementation logic for key words highlight
/// </summary>
private static void ApplyAllHighlight(BindableRichTextBox rtb)
{
try
{
if (rtb != null)
{
string highlightWords = "(";
for (int i = 0; i < MainWindow.Highlightwords.Count; i++)
{
highlightWords += MainWindow.Highlightwords[i];
if (i != MainWindow.Highlightwords.Count - 1)
highlightWords += "|";
}
highlightWords += ")";
Regex reg = new Regex(highlightWords, RegexOptions.Compiled | RegexOptions.IgnoreCase);
var start = rtb.Document.ContentStart;
while (start != null && start.CompareTo(rtb.Document.ContentEnd) < 0)
{
if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
{
var match = reg.Match(start.GetTextInRun(LogicalDirection.Forward));
var textrange = new TextRange(start.GetPositionAtOffset(match.Index, LogicalDirection.Forward), start.GetPositionAtOffset(match.Index + match.Length, LogicalDirection.Backward));
textrange.ApplyPropertyValue(TextElement.BackgroundProperty, new SolidColorBrush(Colors.Yellow));
start = textrange.End;
}
start = start.GetNextContextPosition(LogicalDirection.Forward);
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
//Content of list view remarks column and keywords to be highlighted
//Key word to be highlighted
Highlightwords = new List<string>();
Highlightwords.Add("mment");
Highlightwords.Add("ADD");
Highlightwords.Add("LOCATION");
Highlightwords.Add("arch");
// Remarks in list view
CollRemarks = new ObservableCollection<evcom>();
string remar = "search for added comments in location added";
CollRemarks.Add(new evcom { type = "Info", Operatorid = "1728", remarks = remar });
remar = "searched for added add comments in location added LOCATIONS";
CollRemarks.Add(new evcom { type = "Info", Operatorid = "1783", remarks = remar });