Я использую Caliburn Micro, и у меня есть ListBox, который работает для отображения списка элементов, которые я привязал к нему из моей ViewModel.
Однако сейчас я изучаю, как динамически форматировать каждый ListItem, т.е. в моем случае каждая строка может иметь до N значений, которые находятся между двумя токенами, и мне нужно, чтобы они были отформатированы в полужирном.
Я могу разобрать текст в список, а затем Отметьте, какое слово или часть слов необходимо отформатировать, а какие нет, однако я не уверен, как показать это в моем 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>
Кто-нибудь еще смог достичь чего-то подобного? Заранее благодарим за любые подсказки!
РЕДАКТИРОВАТЬ:
Итак, для большей ясности скажем, у меня есть две строки:
Строка 1 - "Это тест string "
String 2 -" This is также является Test string
Что мне нужно сделать, это отобразить вышеупомянутые строки в ListBox со строками, обернутыми в тэги EM (курсивом в приведенном выше примере), чтобы они были выделены жирным шрифтом и красным цветом.
Теперь я создал список объектов, каждый из которых будет иметь две переменные - содержимое строки и тип строки (выделено или не выделено), разбирают каждую строку и разбивают ее так, чтобы я пометил, какие части можно распечатать как есть, а какие нужно печатать в выделенном формате.
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;
}
}
Итак, в приведенной выше модели у меня есть мой старый подход, в котором я предполагал, что в строке будет только один тег, но когда я понял, что иногда их больше 1, я начал новый подход построения списка представлений обозначение строки, отмечая, какие части должны быть напечатаны нормально, а какие должны быть напечатаны выделенными.
Кроме того, в соответствии с моими стандартами именования, только запускается WPF и C# в месяц или около того go, поэтому изрядно знакомы со всеми соглашениями об именах, извините!