<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Matthew Manela&#039;s Home Page &#187; WPF</title>
	<atom:link href="http://matthewmanela.com/category/wpf/feed/" rel="self" type="application/rss+xml" />
	<link>http://matthewmanela.com</link>
	<description>The life and work of Matthew Manela</description>
	<lastBuildDate>Sun, 25 Jul 2010 18:00:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Converting RTF to HTML</title>
		<link>http://matthewmanela.com/2009/09/28/converting-rtf-to-html/</link>
		<comments>http://matthewmanela.com/2009/09/28/converting-rtf-to-html/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 21:28:00 +0000</pubDate>
		<dc:creator>MattManela</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[RTF]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">http://blogs.msdn.com/matt/archive/2009/09/28/converting-rtf-to-html.aspx</guid>
		<description><![CDATA[Have you ever had the desire to convert some RTF text into HTML? Probably not. But if you do, then you are in luck! I recently had the need to do this conversion and after some searching found out a way to do it by enhancing a sample distributed in the...]]></description>
			<content:encoded><![CDATA[<P>Have you ever had the desire to convert some RTF text into HTML? Probably not. But if you do, then you are in luck! I recently had the need to do this conversion and after some searching found out a way to do it by enhancing a sample distributed in the MSDN library.&nbsp; The sample is called: <A href="http://msdn.microsoft.com/en-us/library/aa972129.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa972129.aspx">XAML to HTML Conversion Demo</A>.&nbsp; </P>
<P>The sample has code which converts HTML to and from a XAML Flow Document.&nbsp; But this doesn’t make things easier until you realize that there is a way to convert RTF to XAML easily. The key is to use <A title=http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx">System.Windows.Controls.RichTextBox</A> which can load RTF from a stream and save it as XAML.&nbsp; This conversion is shown below:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">static</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            var richTextBox = <SPAN style="COLOR: #0000ff">new</SPAN> RichTextBox();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">if</SPAN> (<SPAN style="COLOR: #0000ff">string</SPAN>.IsNullOrEmpty(rtfText)) <SPAN style="COLOR: #0000ff">return</SPAN> "<SPAN style="COLOR: #8b0000"></SPAN>";
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            var textRange = <SPAN style="COLOR: #0000ff">new</SPAN> TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfMemoryStream = <SPAN style="COLOR: #0000ff">new</SPAN> MemoryStream())
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfStreamWriter = <SPAN style="COLOR: #0000ff">new</SPAN> StreamWriter(rtfMemoryStream))
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfStreamWriter.Write(rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfStreamWriter.Flush();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfMemoryStream.Seek(0, SeekOrigin.Begin);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    textRange.Load(rtfMemoryStream, DataFormats.Rtf);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfMemoryStream = <SPAN style="COLOR: #0000ff">new</SPAN> MemoryStream())
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                textRange = <SPAN style="COLOR: #0000ff">new</SPAN> TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                textRange.Save(rtfMemoryStream, DataFormats.Xaml);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                rtfMemoryStream.Seek(0, SeekOrigin.Begin);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfStreamReader = <SPAN style="COLOR: #0000ff">new</SPAN> StreamReader(rtfMemoryStream))
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    <SPAN style="COLOR: #0000ff">return</SPAN> rtfStreamReader.ReadToEnd();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }</PRE></PRE>
<P>With this code we have all we need to convert RTF to HTML. I modified the sample to add this RTF To XAML conversation and then I run that XAML through HTML converter which results in the HTML text. I added an interface to these conversion utilities and converted the sample into a library so that I would be able to use it from other projects.&nbsp; Here is the interface:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"> <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">interface</SPAN> IMarkupConverter
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertXamlToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> xamlText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertHtmlToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> htmlText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">class</SPAN> MarkupConverter : IMarkupConverter
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertXamlToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> xamlText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> HtmlFromXamlConverter.ConvertXamlToHtml(xamlText, <SPAN style="COLOR: #0000ff">false</SPAN>);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertHtmlToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> htmlText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> HtmlToXamlConverter.ConvertHtmlToXaml(htmlText, <SPAN style="COLOR: #0000ff">true</SPAN>);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> RtfToHtmlConverter.ConvertRtfToHtml(rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    }</PRE></PRE>
<P>With this I am now able to convert from RTF to HTML.&nbsp; However, there is one catch - the conversion uses the RichTextBox WPF control which requires a single threaded apartment (STA).&nbsp; Therefore in order to run your code that calls the ConvertRtfToHtml function, it must also be running in a STA.&nbsp; If you can’t have your program run in a STA then you must create a new STA thread to run the conversion. Like this:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">MarkupConverter markupConverter = <SPAN style="COLOR: #0000ff">new</SPAN> MarkupConverter();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var thread = <SPAN style="COLOR: #0000ff">new</SPAN> Thread(ConvertRtfInSTAThread);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var threadData = <SPAN style="COLOR: #0000ff">new</SPAN> ConvertRtfThreadData { RtfText = rtfText };
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.SetApartmentState(ApartmentState.STA);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.Start(threadData);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.Join();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">return</SPAN> threadData.HtmlText;
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">void</SPAN> ConvertRtfInSTAThread(<SPAN style="COLOR: #0000ff">object</SPAN> rtf)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var threadData = rtf <SPAN style="COLOR: #0000ff">as</SPAN> ConvertRtfThreadData;
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   threadData.HtmlText = markupConverter.ConvertRtfToHtml(threadData.RtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">class</SPAN> ConvertRtfThreadData
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> RtfText { <SPAN style="COLOR: #0000ff">get</SPAN>; <SPAN style="COLOR: #0000ff">set</SPAN>; }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> HtmlText { <SPAN style="COLOR: #0000ff">get</SPAN>; <SPAN style="COLOR: #0000ff">set</SPAN>; }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}</PRE></PRE>
<P>Here is the zip contain the code for the Markup converter: <A href="http://blogs.msdn.com/matt/attachment/9900386.ashx" mce_href="http://blogs.msdn.com/matt/attachment/9900386.ashx">MarkupConverter.zip</A></P><img src="http://blogs.msdn.com/aggbug.aspx?PostID=9900386" width="1" height="1">]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2009/09/28/converting-rtf-to-html/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://blogs.msdn.com/matt/attachment/9900386.ashx" length="64021" type="application/x-zip-compressed" />
		</item>
		<item>
		<title>Converting RTF to HTML</title>
		<link>http://matthewmanela.com/2009/09/28/converting-rtf-to-html-2/</link>
		<comments>http://matthewmanela.com/2009/09/28/converting-rtf-to-html-2/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 21:28:00 +0000</pubDate>
		<dc:creator>MattManela</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[RTF]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">/b/matt/archive/2009/09/28/converting-rtf-to-html.aspx</guid>
		<description><![CDATA[Have you ever had the desire to convert some RTF text into HTML? Probably not. But if you do, then you are in luck! I recently had the need to do this conversion and after some searching found out a way to do it by enhancing a sample distributed in the...]]></description>
			<content:encoded><![CDATA[<P>Have you ever had the desire to convert some RTF text into HTML? Probably not. But if you do, then you are in luck! I recently had the need to do this conversion and after some searching found out a way to do it by enhancing a sample distributed in the MSDN library.&nbsp; The sample is called: <A href="http://msdn.microsoft.com/en-us/library/aa972129.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa972129.aspx">XAML to HTML Conversion Demo</A>.&nbsp; </P>
<P>The sample has code which converts HTML to and from a XAML Flow Document.&nbsp; But this doesn’t make things easier until you realize that there is a way to convert RTF to XAML easily. The key is to use <A title=http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx">System.Windows.Controls.RichTextBox</A> which can load RTF from a stream and save it as XAML.&nbsp; This conversion is shown below:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">static</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            var richTextBox = <SPAN style="COLOR: #0000ff">new</SPAN> RichTextBox();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">if</SPAN> (<SPAN style="COLOR: #0000ff">string</SPAN>.IsNullOrEmpty(rtfText)) <SPAN style="COLOR: #0000ff">return</SPAN> "<SPAN style="COLOR: #8b0000"></SPAN>";
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            var textRange = <SPAN style="COLOR: #0000ff">new</SPAN> TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfMemoryStream = <SPAN style="COLOR: #0000ff">new</SPAN> MemoryStream())
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfStreamWriter = <SPAN style="COLOR: #0000ff">new</SPAN> StreamWriter(rtfMemoryStream))
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfStreamWriter.Write(rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfStreamWriter.Flush();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfMemoryStream.Seek(0, SeekOrigin.Begin);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    textRange.Load(rtfMemoryStream, DataFormats.Rtf);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfMemoryStream = <SPAN style="COLOR: #0000ff">new</SPAN> MemoryStream())
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                textRange = <SPAN style="COLOR: #0000ff">new</SPAN> TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                textRange.Save(rtfMemoryStream, DataFormats.Xaml);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                rtfMemoryStream.Seek(0, SeekOrigin.Begin);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfStreamReader = <SPAN style="COLOR: #0000ff">new</SPAN> StreamReader(rtfMemoryStream))
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    <SPAN style="COLOR: #0000ff">return</SPAN> rtfStreamReader.ReadToEnd();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }</PRE></PRE>
<P>With this code we have all we need to convert RTF to HTML. I modified the sample to add this RTF To XAML conversation and then I run that XAML through HTML converter which results in the HTML text. I added an interface to these conversion utilities and converted the sample into a library so that I would be able to use it from other projects.&nbsp; Here is the interface:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"> <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">interface</SPAN> IMarkupConverter
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertXamlToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> xamlText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertHtmlToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> htmlText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">class</SPAN> MarkupConverter : IMarkupConverter
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertXamlToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> xamlText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> HtmlFromXamlConverter.ConvertXamlToHtml(xamlText, <SPAN style="COLOR: #0000ff">false</SPAN>);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertHtmlToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> htmlText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> HtmlToXamlConverter.ConvertHtmlToXaml(htmlText, <SPAN style="COLOR: #0000ff">true</SPAN>);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> RtfToHtmlConverter.ConvertRtfToHtml(rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    }</PRE></PRE>
<P>With this I am now able to convert from RTF to HTML.&nbsp; However, there is one catch - the conversion uses the RichTextBox WPF control which requires a single threaded apartment (STA).&nbsp; Therefore in order to run your code that calls the ConvertRtfToHtml function, it must also be running in a STA.&nbsp; If you can’t have your program run in a STA then you must create a new STA thread to run the conversion. Like this:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">MarkupConverter markupConverter = <SPAN style="COLOR: #0000ff">new</SPAN> MarkupConverter();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var thread = <SPAN style="COLOR: #0000ff">new</SPAN> Thread(ConvertRtfInSTAThread);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var threadData = <SPAN style="COLOR: #0000ff">new</SPAN> ConvertRtfThreadData { RtfText = rtfText };
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.SetApartmentState(ApartmentState.STA);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.Start(threadData);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.Join();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">return</SPAN> threadData.HtmlText;
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">void</SPAN> ConvertRtfInSTAThread(<SPAN style="COLOR: #0000ff">object</SPAN> rtf)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var threadData = rtf <SPAN style="COLOR: #0000ff">as</SPAN> ConvertRtfThreadData;
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   threadData.HtmlText = markupConverter.ConvertRtfToHtml(threadData.RtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">class</SPAN> ConvertRtfThreadData
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> RtfText { <SPAN style="COLOR: #0000ff">get</SPAN>; <SPAN style="COLOR: #0000ff">set</SPAN>; }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> HtmlText { <SPAN style="COLOR: #0000ff">get</SPAN>; <SPAN style="COLOR: #0000ff">set</SPAN>; }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}</PRE></PRE>
<P>Here is the zip contain the code for the Markup converter: <A href="http://blogs.msdn.com/matt/attachment/9900386.ashx" mce_href="http://blogs.msdn.com/matt/attachment/9900386.ashx">MarkupConverter.zip</A></P><img src="http://blogs.msdn.com/aggbug.aspx?PostID=9900386" width="1" height="1">]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2009/09/28/converting-rtf-to-html-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Components-PostAttachments/00-09-90-03-86/MarkupConverter.zip" length="64021" type="application/x-zip-compressed" />
		</item>
		<item>
		<title>Converting RTF to HTML</title>
		<link>http://matthewmanela.com/2009/09/28/converting-rtf-to-html-3/</link>
		<comments>http://matthewmanela.com/2009/09/28/converting-rtf-to-html-3/#comments</comments>
		<pubDate>Mon, 28 Sep 2009 21:28:00 +0000</pubDate>
		<dc:creator>MattManela</dc:creator>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[RTF]]></category>
		<category><![CDATA[WPF]]></category>
		<category><![CDATA[XAML]]></category>

		<guid isPermaLink="false">/b/matt/archive/2009/09/28/converting-rtf-to-html.aspx</guid>
		<description><![CDATA[Have you ever had the desire to convert some RTF text into HTML? Probably not. But if you do, then you are in luck! I recently had the need to do this conversion and after some searching found out a way to do it by enhancing a sample distributed in the...]]></description>
			<content:encoded><![CDATA[<P>Have you ever had the desire to convert some RTF text into HTML? Probably not. But if you do, then you are in luck! I recently had the need to do this conversion and after some searching found out a way to do it by enhancing a sample distributed in the MSDN library.&nbsp; The sample is called: <A href="http://msdn.microsoft.com/en-us/library/aa972129.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa972129.aspx">XAML to HTML Conversion Demo</A>.&nbsp; </P>
<P>The sample has code which converts HTML to and from a XAML Flow Document.&nbsp; But this doesn’t make things easier until you realize that there is a way to convert RTF to XAML easily. The key is to use <A title=http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.controls.richtextbox.aspx">System.Windows.Controls.RichTextBox</A> which can load RTF from a stream and save it as XAML.&nbsp; This conversion is shown below:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">static</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            var richTextBox = <SPAN style="COLOR: #0000ff">new</SPAN> RichTextBox();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">if</SPAN> (<SPAN style="COLOR: #0000ff">string</SPAN>.IsNullOrEmpty(rtfText)) <SPAN style="COLOR: #0000ff">return</SPAN> "<SPAN style="COLOR: #8b0000"></SPAN>";
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            var textRange = <SPAN style="COLOR: #0000ff">new</SPAN> TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfMemoryStream = <SPAN style="COLOR: #0000ff">new</SPAN> MemoryStream())
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfStreamWriter = <SPAN style="COLOR: #0000ff">new</SPAN> StreamWriter(rtfMemoryStream))
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfStreamWriter.Write(rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfStreamWriter.Flush();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    rtfMemoryStream.Seek(0, SeekOrigin.Begin);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    textRange.Load(rtfMemoryStream, DataFormats.Rtf);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfMemoryStream = <SPAN style="COLOR: #0000ff">new</SPAN> MemoryStream())
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                textRange = <SPAN style="COLOR: #0000ff">new</SPAN> TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                textRange.Save(rtfMemoryStream, DataFormats.Xaml);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                rtfMemoryStream.Seek(0, SeekOrigin.Begin);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                <SPAN style="COLOR: #0000ff">using</SPAN> (var rtfStreamReader = <SPAN style="COLOR: #0000ff">new</SPAN> StreamReader(rtfMemoryStream))
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                    <SPAN style="COLOR: #0000ff">return</SPAN> rtfStreamReader.ReadToEnd();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">                }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }</PRE></PRE>
<P>With this code we have all we need to convert RTF to HTML. I modified the sample to add this RTF To XAML conversation and then I run that XAML through HTML converter which results in the HTML text. I added an interface to these conversion utilities and converted the sample into a library so that I would be able to use it from other projects.&nbsp; Here is the interface:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"> <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">interface</SPAN> IMarkupConverter
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertXamlToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> xamlText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertHtmlToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> htmlText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">class</SPAN> MarkupConverter : IMarkupConverter
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertXamlToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> xamlText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> HtmlFromXamlConverter.ConvertXamlToHtml(xamlText, <SPAN style="COLOR: #0000ff">false</SPAN>);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertHtmlToXaml(<SPAN style="COLOR: #0000ff">string</SPAN> htmlText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> HtmlToXamlConverter.ConvertHtmlToXaml(htmlText, <SPAN style="COLOR: #0000ff">true</SPAN>);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        {
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">            <SPAN style="COLOR: #0000ff">return</SPAN> RtfToHtmlConverter.ConvertRtfToHtml(rtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">    }</PRE></PRE>
<P>With this I am now able to convert from RTF to HTML.&nbsp; However, there is one catch - the conversion uses the RichTextBox WPF control which requires a single threaded apartment (STA).&nbsp; Therefore in order to run your code that calls the ConvertRtfToHtml function, it must also be running in a STA.&nbsp; If you can’t have your program run in a STA then you must create a new STA thread to run the conversion. Like this:</P><PRE style="BORDER-BOTTOM: #cecece 1px solid; BORDER-LEFT: #cecece 1px solid; PADDING-BOTTOM: 5px; BACKGROUND-COLOR: #fbfbfb; MIN-HEIGHT: 40px; PADDING-LEFT: 5px; WIDTH: 650px; PADDING-RIGHT: 5px; OVERFLOW: auto; BORDER-TOP: #cecece 1px solid; BORDER-RIGHT: #cecece 1px solid; PADDING-TOP: 5px"><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">MarkupConverter markupConverter = <SPAN style="COLOR: #0000ff">new</SPAN> MarkupConverter();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> ConvertRtfToHtml(<SPAN style="COLOR: #0000ff">string</SPAN> rtfText)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var thread = <SPAN style="COLOR: #0000ff">new</SPAN> Thread(ConvertRtfInSTAThread);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var threadData = <SPAN style="COLOR: #0000ff">new</SPAN> ConvertRtfThreadData { RtfText = rtfText };
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.SetApartmentState(ApartmentState.STA);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.Start(threadData);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   thread.Join();
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">return</SPAN> threadData.HtmlText;
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"></PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">void</SPAN> ConvertRtfInSTAThread(<SPAN style="COLOR: #0000ff">object</SPAN> rtf)
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   var threadData = rtf <SPAN style="COLOR: #0000ff">as</SPAN> ConvertRtfThreadData;
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   threadData.HtmlText = markupConverter.ConvertRtfToHtml(threadData.RtfText);
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">        
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px"><SPAN style="COLOR: #0000ff">private</SPAN> <SPAN style="COLOR: #0000ff">class</SPAN> ConvertRtfThreadData
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">{
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> RtfText { <SPAN style="COLOR: #0000ff">get</SPAN>; <SPAN style="COLOR: #0000ff">set</SPAN>; }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">   <SPAN style="COLOR: #0000ff">public</SPAN> <SPAN style="COLOR: #0000ff">string</SPAN> HtmlText { <SPAN style="COLOR: #0000ff">get</SPAN>; <SPAN style="COLOR: #0000ff">set</SPAN>; }
</PRE><PRE style="BACKGROUND-COLOR: #fbfbfb; MARGIN: 0em; WIDTH: 100%; FONT-FAMILY: consolas,'Courier New',courier,monospace; FONT-SIZE: 11px">}</PRE></PRE>
<P>Here is the zip contain the code for the Markup converter: <A href="http://blogs.msdn.com/matt/attachment/9900386.ashx" mce_href="http://blogs.msdn.com/matt/attachment/9900386.ashx">MarkupConverter.zip</A></P><img src="http://blogs.msdn.com/aggbug.aspx?PostID=9900386" width="1" height="1">]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2009/09/28/converting-rtf-to-html-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Components-PostAttachments/00-09-90-03-86/MarkupConverter.zip" length="64021" type="application/x-zip-compressed" />
		</item>
		<item>
		<title>CollectionView.DeferRefresh() : My new best friend</title>
		<link>http://matthewmanela.com/2008/03/11/collectionview-deferrefresh-my-new-best-friend/</link>
		<comments>http://matthewmanela.com/2008/03/11/collectionview-deferrefresh-my-new-best-friend/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:26:35 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=307</guid>
		<description><![CDATA[Well, maybe not best friend but its a nice function.&#160; When working with bound collections in WPF you often end up dealing with a CollectionView.&#160; This is the MSDN documentation description of a CollectionView : You can think of a collection view as a layer on top of a binding source collection that allows you [...]]]></description>
			<content:encoded><![CDATA[<p><P>Well, maybe not best friend but its a nice function.&nbsp; When working with bound collections in WPF you often end up dealing with a <A href="http://msdn.microsoft.com/en-us/library/system.windows.data.collectionview.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.data.collectionview.aspx">CollectionView</A>.&nbsp; This is the MSDN documentation description of a CollectionView :</P></p>

<p><BLOCKQUOTE>
<P>You can think of a collection view as a layer on top of a binding source collection that allows you to navigate and display the collection based on sort, filter, and group queries, all without having to manipulate the underlying source collection itself. </P>
</BLOCKQUOTE></p>

<p><P>As stated above the main use of the CollectionView is to enable modifying the visible collection without actually changing the underlying data.&nbsp; In the application I am working on I let the user change what a ListBox is sorted by.&nbsp; This is the code I originally had:</P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> ICollectionView dataView = CollectionViewSource.GetDefaultView(listBox.ItemsSource);</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> dataView.SortDescriptions.Clear();</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN> SortDescription sd = <SPAN style="COLOR: #0000ff">new</SPAN> SortDescription(newField, ListSortDirection.Ascending);</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN> dataView.SortDescriptions.Add(sd);</PRE></DIV></DIV>
<P><BR>The problem with this code is that it causes the view to refresh twice! The Clear and Add function both trigger a SortDescriptionsChanged event which leads to a Refresh of the view.&nbsp; This problem becomes worse when you are also adding or changing filter in addition to sort descriptions and your collection is very large.&nbsp; This could visibly slow you application.</P></p>

<p><P>This is where my friend DeferRefresh comes in.&nbsp; If you change the code above to this:</P></p>

<p><DIV style="BORDER-BOTTOM: gray 1px solid; BORDER-LEFT: gray 1px solid; PADDING-BOTTOM: 4px; LINE-HEIGHT: 12pt; BACKGROUND-COLOR: #f4f4f4; MARGIN: 20px 0px 10px; PADDING-LEFT: 4px; WIDTH: 97.5%; PADDING-RIGHT: 4px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; MAX-HEIGHT: 200px; FONT-SIZE: 8pt; OVERFLOW: auto; BORDER-TOP: gray 1px solid; CURSOR: text; BORDER-RIGHT: gray 1px solid; PADDING-TOP: 4px">
<DIV style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px">
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   1:</SPAN> ICollectionView dataView = CollectionViewSource.GetDefaultView(listBox.ItemsSource);</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   2:</SPAN> <SPAN style="COLOR: #0000ff">using</SPAN> (dataView.DeferRefresh())</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   3:</SPAN> {</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   4:</SPAN>     dataView.SortDescriptions.Clear();</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   5:</SPAN>     SortDescription sd = <SPAN style="COLOR: #0000ff">new</SPAN> SortDescription(newField, ListSortDirection.Ascending);</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   6:</SPAN>     dataView.SortDescriptions.Add(sd);</PRE>
<PRE style="BORDER-BOTTOM-STYLE: none; PADDING-BOTTOM: 0px; LINE-HEIGHT: 12pt; BORDER-RIGHT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; MARGIN: 0em; PADDING-LEFT: 0px; WIDTH: 100%; PADDING-RIGHT: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-TOP-STYLE: none; COLOR: black; FONT-SIZE: 8pt; BORDER-LEFT-STYLE: none; OVERFLOW: visible; PADDING-TOP: 0px"><SPAN style="COLOR: #606060">   7:</SPAN> }</PRE></DIV></DIV>
<P>Now the CollectionView will only be refreshed once! All the methods inside the using block will no longer cause a refresh, they will just indicate that a refresh is needed. Then when the code leaves the using block the method EndDefer() is called which just refreshes the CollectionView if needed.</P></p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/collectionview-deferrefresh-my-new-best-friend/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The two most important WPF Tools</title>
		<link>http://matthewmanela.com/2008/03/11/the-two-most-important-wpf-tools/</link>
		<comments>http://matthewmanela.com/2008/03/11/the-two-most-important-wpf-tools/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 22:23:52 +0000</pubDate>
		<dc:creator>Matt</dc:creator>
				<category><![CDATA[WPF]]></category>

		<guid isPermaLink="false">http://matthewmanela.com/?p=299</guid>
		<description><![CDATA[I have been working a lot with WPF and I found the following two FREE tools to be extremely helpful. The first is: XamlPadX &#8211; (http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx) This is an enhanced version of XamlPad which comes with the .NET SDK.&#160; This is a light weight tool which parses and renders XAML code visually.&#160; It adds (in [...]]]></description>
			<content:encoded><![CDATA[<p><P>I have been working a lot with WPF and I found the following two FREE tools to be extremely helpful.</P></p>

<p><P>The first is:</P></p>

<p><P><A href="http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx" mce_href="http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx"><STRONG>XamlPadX</STRONG></A><STRONG> &#8211; (</STRONG><A title=http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx href="http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx" mce_href="http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx"><STRONG>http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx</STRONG></A><STRONG>)</STRONG></P></p>

<p><P>This is an enhanced version of XamlPad which comes with the .NET SDK.&nbsp; This is a light weight tool which parses and renders XAML code visually.&nbsp; It adds (in addition to just rendering XAML) a command interpreter, visual tree explorer, add-in support and much more.</P></p>

<p><P>I find this tool very usefull when I want to just play around with XAML and see how things render.&nbsp; It is quicker than firing up VS and using the Cider designer.</P></p>

<p><P><A href="http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx" mce_href="http://blogs.msdn.com/llobo/archive/2007/12/19/xamlpadx-v3-0.aspx"><IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" border=0 alt=image src="http://blogs.msdn.com/blogfiles/matt/WindowsLiveWriter/TwomostimportantWPFTools_7BAA/image_6.png" width=354 height=247 mce_src="http://blogs.msdn.com/blogfiles/matt/WindowsLiveWriter/TwomostimportantWPFTools_7BAA/image_6.png"></A> </P></p>

<p><P>The other tool is:</P></p>

<p><P><A href="http://www.blois.us/Snoop/" mce_href="http://www.blois.us/Snoop/"><STRONG>Snoop</STRONG></A><STRONG> &#8211; (</STRONG><A title=http://www.blois.us/Snoop/ href="http://www.blois.us/Snoop/" mce_href="http://www.blois.us/Snoop/"><STRONG>http://www.blois.us/Snoop/</STRONG></A><STRONG>)</STRONG></P></p>

<p><P>Snoop is a visual debugger for WPF application.&nbsp; When any WPF application is running you can use snoop to view its visual tree and all the elements properties.&nbsp; You can search for any element, view its properties, change its properties and see how the application changes.</P></p>

<p><P>This program really helps in understanding what is going on in your WPF application and finding problems.</P></p>

<p><P><A href="http://www.blois.us/Snoop/" mce_href="http://www.blois.us/Snoop/"><IMG style="BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; BORDER-TOP: 0px; BORDER-RIGHT: 0px" border=0 alt=image src="http://blogs.msdn.com/blogfiles/matt/WindowsLiveWriter/TwomostimportantWPFTools_7BAA/image_5.png" width=354 height=294 mce_src="http://blogs.msdn.com/blogfiles/matt/WindowsLiveWriter/TwomostimportantWPFTools_7BAA/image_5.png"></A></P></p>
]]></content:encoded>
			<wfw:commentRss>http://matthewmanela.com/2008/03/11/the-two-most-important-wpf-tools/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
