Continuing support for simple HTML display in Silverlight [HtmlTextBlock sample updated for Silverlight 2 Beta 1!]


This blog has moved to a new location and comments have been disabled.

All old posts, new posts, and comments can be found on The blog of dlaa.me.

See you there!

Comments (16)
  1. Brad Abrams posted links the the SL2 poster, Shawn Wildermuth has links out to a discussion of a Cross

  2. Depuis la mise a disponibilité de Silverlight 2 au Mix08 il y a eu beaucoup d’articles, de blogs sur

  3. eibrahim says:

    Thanks for this control, but it is not working for me.  I tried to add it to a databound listbox and it wouldn’t show up.

    My listbox item temple looks like this:

    <DataTemplate x:Key="ItemReviewTemplate">

               <Grid Height="90" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"

                     Visibility="Visible">

                   <StackPanel x:Name="pnlItemInfo" Width="Auto" HorizontalAlignment="Stretch">

                       <TextBlock x:Name="txtSummary2" Text="{Binding Summary}" TextWrapping="Wrap"

                                            HorizontalAlignment="Stretch" MinWidth="200"></TextBlock>

                       <local:HtmlTextBlock x:Name="txtSummary" Text="{Binding Summary}" TextWrapping="Wrap"

                                            HorizontalAlignment="Stretch" MinWidth="200">

                       </local:HtmlTextBlock>

                       <!–<local:HtmlTextBlock x:Name="txtContent" Text="{Binding Content}"

                                            TextWrapping="Wrap" HorizontalAlignment="Stretch"

                                            MinWidth="200" UseDomAsParser="true"></local:HtmlTextBlock>–>

                   </StackPanel>

               </Grid>

           </DataTemplate>

  4. Delay says:

    eibrahim,

    This is a consequence of me doing as simple a port as possible. 🙁 Recall that Silverlight 1.1 Alpha did not support data binding, so this issue simply couldn’t exist there. Now that Silverlight 2 Beta 1 supports data binding, HtmlTextBlock needs a minor change to support it. In particular, its properties need to be backed by DependencyProperties in order for data binding to work as we’d like. I’ll be updating the sample soon to add this support, but for now if you go ahead and replace the Text property definition of the HtmlTextBlock class with the following, then your scenario should work fine:

       public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(HtmlTextBlock),

           delegate(DependencyObject o, DependencyPropertyChangedEventArgs e) { ((HtmlTextBlock)o).ParseAndSetText((string)(e.NewValue)); });

       public string Text

       {

           get { return (string)GetValue(TextProperty); }

           set { SetValue(TextProperty, value); }

       }

    Please let me know if this doesn’t solve the problem!

  5. Delay's Blog says:

    In the comments to my post about porting the HtmlTextBlock sample to Silverlight 2 Beta 1 , kind reader

  6. Delay's Blog says:

    A customer recently asked about an update to my HtmlTextBlock sample for the newly released Silverlight

  7. Delay's Blog says:

    A couple of readers have asked about an update to my long-running HtmlTextBlock sample for Silverlight

  8. Delay's Blog says:

    I updated my HtmlTextBlock sample for RTW last night and got an email from kind reader Ed Silverton this

  9. mike868686 says:

    Hi David

    Thanks so much. Can i ask, @ my Page.xaml.cs, how do i pass in the values of method 'setText' into my 'm_textBlock'? (m_textBlock is a TextBlock declared @ Page.xaml, utilizing 'Loaded="fullNameControl_Loaded"' as i have difficulty accessing an attribute within a datatemplate even with the textblock's name declared then)

    snippet @ Page.xaml.cs:

    public TextBlock m_textBlock;

           void fullNameControl_Loaded(object sender, RoutedEventArgs e)

           {

               if (maxheight.Equals(40))

               {

                   m_textBlock = sender as TextBlock;

                   m_textBlock.MaxHeight = 40;

               }

               if (maxheight.Equals(50))

               {

                   m_textBlock = sender as TextBlock;

                   m_textBlock.MaxHeight = 50;

               }

               if (maxheight.Equals(65))

              {

                  m_textBlock = sender as TextBlock;

                  m_textBlock.MaxHeight = 65;

              }

           }

           [ScriptableMember]

           public void SetText(string text, string fontFamily, string fontSizeString)

           {

               // Parse font size passed in as string

               var fontSize = double.Parse(fontSizeString);

               // Apply changes to HtmlTextBlock

               this.m_textBlock.FontFamily = new FontFamily(fontFamily);

               this.m_textBlock.FontSize = fontSize;

               // Reset text as a workaround for unusual TextBlock behavior

               this.m_textBlock.Text = "";

               this.m_textBlock.Text = text;

           }

    snippet @ Page.xaml:

    <local:HtmlTextBlock x:Name="htmlTextBlock" Text="{Binding NewsBody}" Grid.Row="1" Grid.Column="1"  Margin="5,3,3,3" HorizontalAlignment="Left" VerticalAlignment="Top" TextWrapping="Wrap" Loaded="fullNameControl_Loaded" UseDomAsParser="True" />

  10. Delay says:

    mike868686,

    I don't think I understand the question. 🙁 The SetText method is marked "ScriptableMember" which allows it to be accessed via JavaScript; it already appears to be setting the m_textBlock's Text property which is how it would set the text. I don't think the Loaded event is relevant here, or?

  11. mike868686 says:

    Hi David

    Thank you. In my case, i had to include the Loaded event within <local:HtmlTextBlock x:Name="htmlTextBlock" Text="{Binding NewsBody}" Grid.Row="1" Grid.Column="1"  Margin="5,3,3,3" HorizontalAlignment="Left" VerticalAlignment="Top" TextWrapping="Wrap" Loaded="fullNameControl_Loaded" UseDomAsParser="True" /> as i could not access htmlTextBlock @ Page.xaml.cs. From my understanding, i had to include the event as a workaround to access one of the attributes within the textblock, which was embedded within a datatemplate. Had wanted to avoid solutions like 'RootTreeVisual' etc.

    Im sure if i had not included event, your control will work, when i can access 'htmlTextBlock' from code behind. However, based on my situation, will you recommend a way as to how i may make the HTML parser work? More than willing to provide code snippets if need be.

    Hope to hear from you soon. Regards 🙂

  12. Delay says:

    mike868686,

    It sounds like your question is about finding controls within a DataTemplate rather than something to do with HtmlTextBlock. (In other words, you'd have the same difficulty with standard TextBlock.) If so, there are some tricks that can be used: VisualTreeHelper, custom attached property, etc.. If you do a web search, you should be able to find some good suggestions. Here's something I found just now that seems helpful:

    antonidol.wordpress.com/…/accessing-properties-and-objects-in-silverlight-datatemplates-using-loaded-and-findname

  13. mike868686 says:

    Hi David

    Thanks so much! 🙂 absolutely the most relevant & helpful link i've seen so far for the past 3 days. Assuming that im taking reference from the link you provided me with, will you provide me some sample as to how i may achieve HTML parsing & yet locate the 'htmlTextBlock' @ the same time? Still figuring & fiddling about with the code though 🙁

  14. mike868686 says:

    FYI David,

    I have skimmed down to the following code & have affirmed that 't' reads in the 'htmlTextBlock'. (ie. able to access the textblock within the datatemplate) But somehow, the output still does not parse HTML, with all the tags still present with the data. Am i missing out something obvious as to what i must ensure if i am to implement the custom HTML textblock?

    Much appreciated, your help will make my day. 🙂

    @ Page.xaml.cs:

    public HtmlTextBlock t;

           void htmlTextBlock_Loaded(object sender, RoutedEventArgs e)

           {

               Grid grd = sender as Grid;

               if (grd != null)

                   t = grd.FindName("htmlTextBlock") as HtmlTextBlock;                            

           }

           [ScriptableMember]

           public void SetText(string text, string fontFamily, string fontSizeString)

           {

               // Parse font size passed in as string

               var fontSize = double.Parse(fontSizeString);

               // Apply changes to HtmlTextBlock

               t.FontFamily = new FontFamily(fontFamily);

               t.FontSize = fontSize;            

               // Reset text as a workaround for unusual TextBlock behavior

               t.Text = "";

               t.Text = text;

           }

  15. mike868686 says:

    Hi David

    To be specific, in my case now, htmlTextBlock works. However it is only able to render in bold, italic without the html tags present with the data. If i change the font-family, font-size or font-colour of the data, the changes will not be reflected. I suspect it has to do with method 'SetText', as i could not see any parameter values passed in when i perform debugging. Please guide me as to how & where these values are derived from? Thanks & regards.

    Looking forward to your positive response.

  16. Delay says:

    mike868686,

    If you follow some of the back links to my original HtmlTextBlock post, you'll see that I only ever suported the very simplest of HTML tags like B and I as this was more of a proof of concept than anything else. 🙂 So it sounds like things are now working as they should – though if you'd like to add support for additional elements, that could be cool!

    FYI that you may not need to – have a look at this which may already do what you want: blogs.msdn.com/…/teaching-an-old-dog-new-tricks-updated-htmltextblock-implementation-uses-richtextbox-to-support-images-and-hyperlinks.aspx

Comments are closed.