I struggled with this for all of the same reasons and eventually came up with a solution. I need to show a bunch from the inside in a ListBox for my Septic Companion application . Right now, my decision is only bold or italic (like everything I cared about), but it would be easy to change it to deal with more. First, in my ViewModel, I wrote a procedure to return a TextBlock given an HTML string.
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
Then I just need a way to build this in my XAML. This may not be the best solution, but I first did another procedure to return a StackPanel containing this TextBlock with the text I wanted.
public StackPanel WordBlock { get { StackPanel sp = new StackPanel(); TextBlock tbWord = MakeFormattedTextBlock("<b>" + Word + "</b>: " + Desc); sp.Children.Add(tbWord); return sp; } }
To bind this to a visible control, I made a DataTemplate for my ListBox, which just read the entire StackPanel from my view model.
<DataTemplate x:Key="WordInList2"> <ContentControl Content="{Binding WordBlock}"/> </DataTemplate>
As I said, there may be parts of it that don't work as elegantly as they can be, but that did what I wanted. Hope this works for you!
Chris rae
source share