我需要从可能很长的文本中裁剪并显示指定的关键字(带有一些单词)。
想象一下这样的文字:
Lorem ipsum dolor sit amet,consectetur adipiscing elit,sed do eiusmod tempor incididunt ut labore et dolore magna aliqua
关键字:
iscing
我的目标是在一些宽度非常有限的TextBlock中显示如下内容:
consectetur adip iscing elit
或(更好)
... consectetur adip iscing elit ...
关键字周围的字数应基于可用空间。
我们使用MVVM模式。有没有人有一个有效的解决方案?非常感谢
编辑:我现在不想突出显示关键字。
编辑2:为了简单起见,假设我们只想显示第一次出现的" iscing"关键字。
编辑3:再次清楚 - 假设你在应用程序(文档)中有一些大文本和其他应用程序组件,如TextBlock,从大文本中显示搜索的关键字,并带有一些单词,以便用户可以获取上下文。 Textblock可以在运行时调整大小,因此它应该显示更多单词(基于大小)。理想情况下,关键字应该位于Textblock中间的某个位置。
答案 0 :(得分:2)
此功能按您的要求执行:
public string Truncate(string input, string match, int nbCharMaxBefore, int nbCharMaxAfter)
{
var inputSplit = input.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
var index = 0;
while (index < inputSplit.Length)
{
if (inputSplit[index].Contains(match)) break;
index++;
}
if (index == inputSplit.Length)
{
// No match
return String.Empty;
}
// Adds all the words before the match as long as the sum of all the words is not greater than the specified limit
var previousWords = new List<string>();
var i = index - 1;
while (i >= 0)
{
var previousWord = inputSplit[i];
if (previousWord.Length + previousWords.Sum(w => w.Length) < nbCharMaxBefore)
{
previousWords.Insert(0, previousWord);
}
else
{
break;
}
i--;
}
// Adds all the words after the match as long as the sum of all the words is not greater than the specified limit
var nextWords = new List<string>();
i = index + 1;
while (i < inputSplit.Length)
{
var nextWord = inputSplit[i].TrimEnd(',');
if (nextWord.Length + nextWords.Sum(w => w.Length) < nbCharMaxAfter)
{
nextWords.Add(nextWord);
}
else
{
break;
}
i++;
}
var prev = String.Join(" ", previousWords);
var next = String.Join(" ", nextWords);
return $"...{prev} {inputSplit[index]} {next}...";
}
你可以这样使用它:
var input = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua";
var match = "iscing";
var nbCharMaxBefore = 15;
var nbCharMaxAfter = 5;
var truncatedStr = Truncate(input, match, nbCharBefore, nbCharAfter); // ...consectetur adipiscing elit...
关于MVVM方式,考虑到你绑定的属性是MyText
,只需绑定另一个属性:
public string MyTruncatedText
{
get { return Truncate(this.MyText, this.MyMatch, this.NbCharBefore, this.NbCharAfter); }
}
最后,在MyText
的setter中,您想要调用NotifyPropertyChanges(nameof(MyTruncatedProperty))
或MVVM工具包中的等效项。
答案 1 :(得分:0)
Databind跟随文本块到适当的属性。
<TextBlock>
<Run x:Name="pre" Text="{Binding PrecedingText}" />
<Run x:Name="search" Text="{Binding SearchText}" FontWeight="Bold" />
<Run x:Name="succeeding" Text="{Binding SucceedingText}" />
</TextBlock>
使用以下视图模型类。
class SearchResult
{
public PrecedingText { get; set; }
public SearchText { get; set; }
public SucceedingText { get; set; }
}