More on "Avalon" RichTextBox


As promised, I learned more so I'm sharing.  Last time I figured out how to stuff plain text into the RichTextBox, but that's not very "rich", is it? 


How do I put RTF (rich text format) into a RichTextBox?
It turns out the support for this seems to be through the TextRange class.  TextRange offers a "Load" method which takes a string representing a data format (which you can pick from the DataFormats class) and a stream.  If you currently have a string of RTF formatting, you can stuff the string in a MemoryStream, then pass it to the TextRange.  Here's a handy helper function for it:



        private static void LoadRTF(string rtf, RichTextBox richTextBox) {


            if (string.IsNullOrEmpty(rtf)) {
                throw new ArgumentNullException();
            }


            TextRange textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);


            //Create a MemoryStream of the Rtf content
           
            using (MemoryStream rtfMemoryStream = new MemoryStream()) {
                using (StreamWriter rtfStreamWriter = new StreamWriter(rtfMemoryStream)) {
                    rtfStreamWriter.Write(rtf);
                    rtfStreamWriter.Flush();
                    rtfMemoryStream.Seek(0, SeekOrigin.Begin);


                    //Load the MemoryStream into TextRange ranging from start to end of RichTextBox.
                    textRange.Load(rtfMemoryStream, DataFormats.Rtf);
                }
            }
        }


How do I load a file with "rich" content in it?
Here again, you can use the TextRange class to load, but you pass in a FileStream instead of a MemoryStream.
 


   private static void LoadFile(string filename, RichTextBox richTextBox) {
            if (string.IsNullOrEmpty(filename)) {
                throw new ArgumentNullException();
            }
            if (!File.Exists(filename)) {
                throw new FileNotFoundException();
            }


            // open the file for reading
            using (FileStream stream = File.OpenRead(filename)) {
                // create a TextRange around the entire document
                TextRange documentTextRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
               
                // sniff out what data format you've got
                string dataFormat = DataFormats.Text;
                string ext = System.IO.Path.GetExtension(filename);
                if (String.Compare(ext, ".xaml",true) == 0) {
                    dataFormat = DataFormats.Xaml;
                }
                else if (String.Compare(ext, ".rtf", true) == 0) {
                    dataFormat = DataFormats.Rtf;
                }
                documentTextRange.Load(stream, dataFormat);
            }       
        }


How do I Save a file with "rich" content in it?
TextRange also has a Save!  Here's the code


    private static void SaveFile(string filename, RichTextBox richTextBox) {
            if (string.IsNullOrEmpty(filename)) {
                throw new ArgumentNullException();
            }
          


            // open the file for reading
            using (FileStream stream = File.OpenWrite(filename)) {
                // create a TextRange around the entire document
                TextRange documentTextRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);


                // sniff out what data format you've got
                string dataFormat = DataFormats.Text;
                string ext = System.IO.Path.GetExtension(filename);
                if (String.Compare(ext, ".xaml", true) == 0) {
                    dataFormat = DataFormats.Xaml;
                }
                else if (String.Compare(ext, ".rtf", true) == 0) {
                    dataFormat = DataFormats.Rtf;
                }
                documentTextRange.Save(stream, dataFormat);
            }
        }


Putting it all together - a very simple editor

Replacing the contents of the Window with this DockPanel, adding the SaveFile, LoadFile helper methods and the event handlers for open and save, we can get a very simple rich text editor.

  <!-- Window1.xaml -->
  <DockPanel>
    <Menu DockPanel.Dock="Top">
      <MenuItem Header="_File">
        <MenuItem Header="_Open File" Click="OnOpenFile"/>
        <MenuItem Header="_Save" Click="OnSaveFile"/>
        <Separator/>
        <MenuItem Header="E_xit" Click="OnExit"/>
      </MenuItem>     
    </Menu>
    <RichTextBox Name="richTextBox1"></RichTextBox>    
  </DockPanel>


        // Window1.xaml.cs
        private void OnExit(object sender, EventArgs e) {
            this.Close();
        }
        private void OnOpenFile(object sender, EventArgs e) {
            Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog();
            ofd.Filter = "Text Files (*.txt; *.xaml; *.rtf)|*.txt;*.xaml;*.rtf";
            ofd.Multiselect = false;
            if (ofd.ShowDialog() == true) {
                LoadFile(ofd.SafeFileName, richTextBox1);
            }


        }
        private void OnSaveFile(object sender, EventArgs e) {
            Microsoft.Win32.SaveFileDialog sfd = new Microsoft.Win32.SaveFileDialog();
            sfd.Filter = "Text Files (*.txt; *.xaml; *.rtf)|*.txt;*.xaml;*.rtf";
            if (sfd.ShowDialog() == true) {
                SaveFile(sfd.SafeFileName, richTextBox1);
            }
        }


 

Comments (11)
  1. Thanks for the info, looks great!

    When are we going to see (x)HTML support? Very very very few people use RTF anymore, HTML is the standard and MSHTML.dll is getting VERY long in the tooth.

    Sometime soon I hope!

  2. Paul Winwood says:

    Is this post-December CTP because I can not find TextRange.Load and TextRange.Save methods in my installation of these bits?

  3. jfoscoding says:

    Paul, it might be I just upgraded my build, so I may have jumped the gun.

  4. jfoscoding says:

    Thanks James! Re XHTML, you might want to suggest it over on the avalon MSDN forum…

    https://forums.microsoft.com/MSDN/ShowForum.aspx?ForumID=119&SiteID=1

  5. jfoscoding says:

    Aha, Paul yes this looks to be new methods to look forward to in the next CTP – these replace TextRange.Xml.

  6. Sheva says:

    Jessica,the WINFX SDK January CTP download link doesn’t work in my region, can you report this problem up to the WINFX team?

    Hopefully they can fix the download link as soon as possible.

    Sheva

  7. jfoscoding says:

    RE: WINFX SDK/January CTP, it looks like this is expected:

    http://www.microsoft.com/downloads/details.aspx?FamilyId=61DD9CA7-1668-42E4-BD37-03716DD83E53&displaylang=en

    Additional Information

    This January CTP is for English only. If you are targeting a non-English platform or if you wish to view WinFX resources in a different language, you will need to use the December CTP. You can then download the appropriate language version of the WinFX language pack. The December CTP language packs are available in German and Japanese.

    この January CTP は英語のみです。英語以外のプラットフォームを対象にする場合、または異なる言語で WinFX リソースを表示する場合は、December CTP を使用してください。その後、WinFX Language Pack の適切な言語バージョンをダウンロードすることができます。この December CTP では、ドイツ語および日本語の Language Pack を利用することができます。

    Der CTP vom Januar ist nur auf Englisch verfügbar. Wenn Sie auf einer nicht-englischen Plattform installieren oder WinFX-Ressourcen in einer anderen Sprache anzeigen möchten, müssen Sie den CTP vom Dezember verwenden. Sie können sich dann die entsprechende Sprachversion des WinFX Language Packs herunterladen. Die Language Packs für den Dezember-CTP sind auf Deutsch und Japanisch verfügbar.

  8. Sheva says:

    Well, I think you don’t get into what I meant previously.

    when I followed the SDK download link, I got this in my browser:

    Internal Server Error – Read

    The server encountered an internal error or misconfiguration and was unable to complete your request.

    Reference #3.13dc4bca.1137898399.c131d6

    probably you can try it yourself:

    http://www.microsoft.com/downloads/details.aspx?familyid=64750EEF-D4A7-4CC8-92F2-9A201268A231&displaylang=en

  9. jfo's coding says:

    I thought I’d put up a few good reads:

    Mapping PIs are going away in the next CTP. Rob promises to…

  10. Here is a simple function that will convert RTF data on the clipboard to XAML: /// &lt;summary&gt; ///

Comments are closed.

Skip to main content