Я боролся с этим по тем же причинам и в конце концов нашел решение. Мне нужно показать их несколько в ListBox для моего приложения Compticion от Septic . Прямо сейчас мое решение имеет дело только с жирным шрифтом или курсивом (как это все, о чем я заботился), но было бы легко изменить его, чтобы иметь дело с большим количеством. Во-первых, в моей ViewModel я написал процедуру для возврата TextBlock с заданной строкой HTML.
private TextBlock MakeFormattedTextBlock(string shtml)
{
TextBlock tb = new TextBlock();
Run temprun = new Run();
int bold = 0;
int italic = 0;
do
{
if ((shtml.StartsWith("<b>")) | (shtml.StartsWith("<i>")) |
(shtml.StartsWith("</b>")) | (shtml.StartsWith("</i>")))
{
bold += (shtml.StartsWith("<b>") ? 1 : 0);
italic += (shtml.StartsWith("<i>") ? 1 : 0);
bold -= (shtml.StartsWith("</b>") ? 1 : 0);
italic -= (shtml.StartsWith("</i>") ? 1 : 0);
shtml = shtml.Remove(0,shtml.IndexOf('>') + 1);
if (temprun.Text != null)
tb.Inlines.Add(temprun);
temprun = new Run();
temprun.FontWeight = ((bold > 0) ? FontWeights.Bold : FontWeights.Normal);
temprun.FontStyle = ((italic > 0) ? FontStyles.Italic : FontStyles.Normal);
}
else // just a piece of plain text
{
int nextformatthing = shtml.IndexOf('<');
if (nextformatthing < 0) // there isn't any more formatting
nextformatthing = shtml.Length;
temprun.Text += shtml.Substring(0, nextformatthing);
shtml = shtml.Remove(0, nextformatthing);
}
} while (shtml.Length > 0);
// Flush the last buffer
if (temprun.Text != null)
tb.Inlines.Add(temprun);
return tb;
}
Тогда мне просто нужен был способ встроить это в мой XAML. Возможно, это не самое лучшее решение, но я сначала сделал другую процедуру, чтобы вернуть StackPanel, содержащую этот TextBlock, с текстом, который я хотел.
public StackPanel WordBlock
{
get
{
StackPanel sp = new StackPanel();
TextBlock tbWord = MakeFormattedTextBlock("<b>" + Word + "</b>: " + Desc);
sp.Children.Add(tbWord);
return sp;
}
}
Чтобы связать это с видимым элементом управления, я затем создал DataTemplate для моего ListBox, который просто считывает весь StackPanel из моей модели представления.
<DataTemplate x:Key="WordInList2">
<ContentControl Content="{Binding WordBlock}"/>
</DataTemplate>
Как я уже сказал, могут быть части этого, которые сделаны не так элегантно, как могли бы, но это сделало то, что я хотел. Надеюсь, это работает для вас!