我正在使用Caliburn Micro,并且有一个ListBox,它可以显示我从ViewModel中绑定到它的项目列表。
然而,我现在正在研究如何动态格式化每个ListItem,即在我的例子中,每个字符串可以有N个值,这些值在两个标记之间,我需要将这些值格式化为粗体。
我能够将文本解析成一个列表,然后标记哪些单词或单词块需要格式化,哪些不需要,但是我不确定如何在我的ListBox中显示这些。我看了一下,有些人推荐使用一个转换器来解析文本字符串?
目前我的listbox的XAML看起来像--当我只需要格式化一个关键字的时候,这是可行的,但是后来我发现一个字符串中可能会出现多个关键字,所以无法再预测结构。
<ListBox ItemsSource="{Binding HighlightList}">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<Run Text="{Binding Path=mStartText}"/>
<Run Text="{Binding Path=mBoldText}"/>
<Run Text="{Binding Path=mEndText}"/>
</TextBlock>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
有没有人能够实现类似的事情?先谢谢大家的提示!
EDIT:
那么,为了进一步明确,让我们假设我有两个字符串。
字符串1 - "这是一个 测试 弦"
字符串2 - "这个 是 也是 测试 绳子
我要做的是在ListBox中显示上述字符串,用EM标签(上面例子中的Italics)包裹的字符串要加粗,字体颜色为红色。
我现在所做的是创建一个列表对象,每个对象将有两个变量--字符串内容,以及字符串类型(高亮或不高亮),并对每个字符串进行解析和分解,这样我就可以标记出哪些部分可以原样打印,哪些需要以高亮格式打印。
ViewModel。
public ObservableCollection<HighlightItem> HighlightList
{
get
{
return _highlightList;
}
set
{
_highlightList = value;
NotifyOfPropertyChange(() => HighlightList);
}
}
public void ParseHighlights()
{
ObservableCollection<HighlightItem> hlList = new ObservableCollection<HighlightItem>();
string START_HL_TOKEN = "<em>";
string END_HL_TOKEN = "</em>";
if (_documentSnippets.Count > 0)
{
foreach (var hlItem in _documentSnippets.Snippets["text"])
{
// Remove tab characters
string temp = hlItem.Replace("\t", "");
// Remove multiple newline characters and replace with a single one
Regex regex = new Regex("(\\n){2,}");
string clean_temp = regex.Replace(temp, "\n");
string startText = "", hlText = "", endText = "";
int start_idx = 0;
int end_idx = 0;
List<string> stringTokenized = new List<string>();
// THIS BELOW IS PART OF MY NEW APPROACH
while(start_idx != clean_temp.Length)
{
end_idx = clean_temp.IndexOf(START_HL_TOKEN, start_idx);
// Highlight token is at the start
if(end_idx == 0)
{
start_idx = end_idx;
end_idx = clean_temp.IndexOf(END_HL_TOKEN, start_idx);
stringTokenized.Add(clean_temp.Substring(start_idx + 4, end_idx - start_idx));
// Move pointer to start of next section, keeping in mind the length of the END token
start_idx = end_idx + 4;
}
else if(end_idx == -1)
{
end_idx = clean_temp.Length;
stringTokenized.Add(clean_temp.Substring(start_idx, end_idx - start_idx));
start_idx = end_idx;
}
else
{
stringTokenized.Add(clean_temp.Substring(start_idx, end_idx - start_idx));
start_idx = end_idx;
end_idx = clean_temp.IndexOf(END_HL_TOKEN, start_idx);
stringTokenized.Add(clean_temp.Substring(start_idx + 4, end_idx - start_idx));
// Move pointer to start of next section
start_idx = end_idx + 4;
}
}
// END OF MY NEW APPROACH
// Token is at the beginning of the snippet
if (hlItem.IndexOf(START_HL_TOKEN) == 0)
{
hlText = clean_temp.Substring(clean_temp.IndexOf(START_HL_TOKEN) + START_HL_TOKEN.Length,
clean_temp.IndexOf(END_HL_TOKEN) - START_HL_TOKEN.Length);
endText = clean_temp.Substring(clean_temp.IndexOf(END_HL_TOKEN) + END_HL_TOKEN.Length,
clean_temp.Length - (clean_temp.IndexOf(END_HL_TOKEN) + END_HL_TOKEN.Length));
}
// Token is at the end of the snippet
else if (clean_temp.IndexOf(END_HL_TOKEN) + END_HL_TOKEN.Length == clean_temp.Length)
{
startText = clean_temp.Substring(0,
clean_temp.Length - clean_temp.IndexOf(START_HL_TOKEN));
hlText = clean_temp.Substring(clean_temp.IndexOf(START_HL_TOKEN),
clean_temp.Length - clean_temp.IndexOf(START_HL_TOKEN));
}
// Token is in the middle of the snippet
else
{
startText = clean_temp.Substring(0,
clean_temp.IndexOf(START_HL_TOKEN));
hlText = clean_temp.Substring(clean_temp.IndexOf(START_HL_TOKEN) + START_HL_TOKEN.Length,
clean_temp.IndexOf(END_HL_TOKEN) - clean_temp.IndexOf(START_HL_TOKEN) - (END_HL_TOKEN.Length - 1));
endText = clean_temp.Substring(clean_temp.IndexOf(END_HL_TOKEN) + END_HL_TOKEN.Length,
clean_temp.Length - clean_temp.IndexOf(END_HL_TOKEN) - END_HL_TOKEN.Length);
}
HighlightItem snippet = new HighlightItem(startText, hlText, endText);
hlList.Add(snippet);
}
HighlightList = hlList;
}
}
所以在上面的模型中,我采用了我的老方法,我假设字符串中只有一个标签,但当我意识到有时会有多个标签时,我开始采用新的方法,建立一个字符串的列表表示,标记哪些部分需要正常打印,哪些需要高亮打印。
另外对我的命名标准,一个多月前才开始使用WPF和C#,所以还不太了解所有的命名习惯,抱歉!
按照Sinatr的提示,我找到了下面的文章,使用一个自定义的附加属性对我来说是个好办法。WPF TextBlock格式化粗体来自字符串属性
随后,我能够提供嵌入标记的字符串,它们将被适当地打印出来! 谢谢你的帮助