locked
Converting HTML To RTF using RichEditBox and RichTextBox

    Question

  • I'm currently trying to port Matthew Manela's "Converting between RTF and XAML" code sample to WinRT

    I've got the HTML to XAML code working, but I've hit a snag when getting it into a RichEditBox.

    Matthew's code is WPF based, and uses the following function to convert XAML to RTF.


    private static string ConvertXamlToRtf(string xamlText) 
    { 
        var richTextBox = new RichTextBox(); 
        if (string.IsNullOrEmpty(xamlText)) return ""; 
        var textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); 
        using (var xamlMemoryStream = new MemoryStream()) 
        { 
            using (var xamlStreamWriter = new StreamWriter(xamlMemoryStream)) 
            { 
                xamlStreamWriter.Write(xamlText); 
                xamlStreamWriter.Flush(); 
                xamlMemoryStream.Seek(0, SeekOrigin.Begin); 
                textRange.Load(xamlMemoryStream, DataFormats.Xaml); 
            } 
        } 
        using (var rtfMemoryStream = new MemoryStream()) 
        { 
            textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); 
            textRange.Save(rtfMemoryStream, DataFormats.Rtf); 
            rtfMemoryStream.Seek(0, SeekOrigin.Begin); 
            using (var rtfStreamReader = new StreamReader(rtfMemoryStream)) 
            { 
                return rtfStreamReader.ReadToEnd(); 
            } 
        } 
    }

    I've tried rewriting this in WinRT using RichEditBox, but come up against some issues. Most noteably, WPF TextRange accepts DataFormat.Xaml (as seen in the code above), but WinRT ITextRange doesn't have this. However, I know that I can inject XAML directly into a RichTextBlock control.

    Is there any way to copy the text from a RichTextBlock and paste it into a RichEditBox, programmatically?

    The only windows store code I can find for converting HTML to RTF is this one, which looks promising but doesn't work very well. I'm sure I can improve on it but I'd rather use the native RTF conversion ability of the RichEditBox, if possible. 


    Monday, February 24, 2014 4:37 PM

Answers

  • You'll have to do the conversion yourself. The RichEdiBox doesn't have any native conversion ability. It renders RTF directly and does not convert it to Xaml. This is different from the WPF implementation, which converts RTF rather than displaying it directly.

    Monday, February 24, 2014 4:45 PM
    Owner

All replies

  • You'll have to do the conversion yourself. The RichEdiBox doesn't have any native conversion ability. It renders RTF directly and does not convert it to Xaml. This is different from the WPF implementation, which converts RTF rather than displaying it directly.

    Monday, February 24, 2014 4:45 PM
    Owner
  • Rob, are you 100% sure about this? I created a sample WinRT App with a WebView containing some HTML and an empty RichEditBox side by side. When I copy and paste the HTML from the WebView to the RichEditBox it retains all formatting. I can then successfully save this as an RTF which opens just fine in WordPad, with full formatting. I can share this example app if you like. This proves that RichEditBox must have some native conversion ability - because the WebView certainly isn't outputting RTF.  

    Below is the WPF solution to the problem. Content is copied from the WebBrowser control to a richTextControl:

    webBrowser.Document.ExecCommand("SelectAll", false, null);
    webBrowser.Document.ExecCommand("Copy", false, null);
    *yourRichTextControl*.Paste(); 

    Unfortunately there's no Document property on WebView, or an ExecCommand method. I can't issue a SelectAll or copy command to the control.

    Friday, February 28, 2014 10:37 AM
  • Rob, I'm delight to inform you that you were wrong. Not delighted by taking you down a peg you understand, but delighted to learn that I actually can do what I'm trying to do. Using a mix of InvokeScript and CaptureSelectedContentToDataPackageAsync(), I have managed to copy content from the WebView to the RichEditBox without needing direct user interaction. 

    I can then save this directly to an RTF file. 

    Here's the code, for anyone interested. 

    // this must be in the HTML doc in the webview function select_body() { var range = document.body.createTextRange(); range.select(); }

    private async void Button_Click(object sender, RoutedEventArgs e) { // invoke the javascript function "select body" // which selects all text in the document body MyWebView.InvokeScript("select_body", null); // Capture selected content to a DataPackage // (normally used for sharing) DataPackage p = await MyWebView.CaptureSelectedContentToDataPackageAsync(); // get RTF content from DataPackage string RTF = await p.GetView().GetRtfAsync(); // send RTF content to RichEditBox MyRichEditBox.Document.SetText(Windows.UI.Text.TextSetOptions.FormatRtf, RTF); }




    • Edited by Roryok Friday, February 28, 2014 11:17 AM
    Friday, February 28, 2014 11:16 AM
  • Very cool! Note though that you changed the question so my answer is still (mostly) right :)

    You're doing the whole conversion in the WebView / DataPackage layer, before the RichEditBox gets involved. You already have RTF before you pass it to the RichEditBox. There isn't any Xaml involved in your conversion at all.

    Friday, February 28, 2014 4:33 PM
    Owner
  • Point taken. But how do you explain that it works through the clipboard? I can manually copy and paste from a WebView to a RichEditBox, and then save that to an RTF. There's no DataPackage involved in this step? 

    As I said, all you have to do is create a sample app with a WebView and a RichEditBox side by side, load some HTML into the WebView and then copy from one to the other. This doesn't work the other way though - I can't copy from the RichEditBox to the WebView. 

    Friday, February 28, 2014 4:38 PM
  • There is no meaningful difference between the clipboard data and the DataPackage data: the DataPackage is how the clipboard is exposed to apps.

    I'm 95% sure the conversion is in the WebView and it puts RTF on the clipboard / in the DataPackage.

    --Rob

    Friday, February 28, 2014 4:50 PM
    Owner