George Shepherd's Windows Forms FAQ
 http://www.syncfusion.com/FAQ/WindowsForms/FAQ_c89c.aspx#q640q
Questions and answers in this FAQ have been collected from newsgroup posts, various mailing lists and the employees of Syncfusion.
 

22. Windows Forms RichTextBox

FAQ Home
   22.1 How can I create and save a RTF file?
   22.2 How can I get a string that contains RTF format codes into a RichTextBox?
   22.3 How do I make the RichTextBox support drag and drop?
   22.4 How do I set the color and font in a RichEditBox?
   22.5 How can I change the FontStyle of a selection without losing the styles that are present?
   22.6 How can I programmatically position the cursor on a given line and character of my richtextbox?
   22.7 How can I load an embedded rich text file into a richtextbox?
   22.8 How can I print my rich text?
   22.9 Where can I find more information on the RTF specification?
   22.10 How can I add a hyperlink to a RichTextBox control?



22.1 How can I create and save a RTF file?


 

One way to do this is to use the RichTextBox.SaveFile method.

 

     private void button1_Click(object sender, System.EventArgs e)
     {
          // Create a SaveFileDialog & initialize the RTF extension
          SaveFileDialog saveFile1 = new SaveFileDialog();
          saveFile1.DefaultExt = "*.rtf";
          saveFile1.Filter = "RTF Files|*.rtf";

          // get a file name from the user
          if(saveFile1.ShowDialog() == DialogResult.OK)
          {
               // Save the RTF contents of the RichTextBox control that
               // was dragged onto the Window Form and populated somehow
               richTextBox1.SaveFile(saveFile1.FileName,
                    RichTextBoxStreamType.RichText); //use to save RTF tags in file
                    //RichTextBoxStreamType.PlainText);//use to save plain text in file
          }     
     }


 


22.2 How can I get a string that contains RTF format codes into a RichTextBox?


Use the Rtf property of the control.


     richTextBox1.Rtf = @"{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fswiss\fcharset0 Arial;}}\viewkind4\uc1\pard\b\i\f0\fs20 This is bold italics.\par }";


 


22.3 How do I make the RichTextBox support drag and drop?


1) Set the AllowDrop property to true
2) Add handlers for both the DragEnter and DragDrop event

     this.richTextBox1.DragEnter += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragEnter);
     this.richTextBox1.DragDrop += new System.Windows.Forms.DragEventHandler(this.richTextBox1_DragEnter);

     ....

     private void richTextBox1_DragEnter(object sender,
               System.Windows.Forms.DragEventArgs e)
     {
          if (((DragEventArgs)e).Data.GetDataPresent(DataFormats.Text))
               ((DragEventArgs)e).Effect = DragDropEffects.Copy;
          else
               ((DragEventArgs)e).Effect = DragDropEffects.None;
     }

     private void richTextBox1_DragDrop(object sender, DragEventArgs e)
     {
          // Loads the file into the control.
          richTextBox1.LoadFile((String)e.Data.GetData("Text"), System.Windows.Forms.RichTextBoxStreamType.RichText);
     }

Here are VB snippets.

      AddHandler Me.richTextBox1.DragEnter, New System.Windows.Forms.DragEventHandler(AddressOf Me.richTextBox1_DragEnter)
      AddHandler Me.richTextBox1.DragDrop, New System.Windows.Forms.DragEventHandler(AddressOf Me.richTextBox1_DragEnter)

     .....


     Private Sub richTextBox1_DragEnter(sender As Object, e As System.Windows.Forms.DragEventArgs)

          If CType(e, DragEventArgs).Data.GetDataPresent(DataFormats.Text) Then
               CType(e, DragEventArgs).Effect = DragDropEffects.Copy
          Else
               CType(e, DragEventArgs).Effect = DragDropEffects.None
          End If

     End Sub 'richTextBox1_DragEnter


     Private Sub richTextBox1_DragDrop(sender As Object, e As DragEventArgs)

          ' Loads the file into the control.
          richTextBox1.LoadFile(CType(e.Data.GetData("Text"), [String]), System.Windows.Forms.RichTextBoxStreamType.RichText)

     End Sub 'richTextBox1_DragDrop

 


22.4 How do I set the color and font in a RichEditBox?


You use the SelectionFont and SelectionColor properties. Make sure the control had focus. Then the following code will set the currently selected text to a red-bold-courier font. If no text is currently selected, then any new text typed (or inserted) will be red-bold-courier.

[C#]
     richTextBox1.Focus();
     richTextBox1.SelectionColor = Color.Red;
     richTextBox1.SelectionFont = new Font ("Courier", 10, FontStyle.Bold);

 

[VB.NET]
     richTextBox1.Focus()
     richTextBox1.SelectionColor = Color.Red
     richTextBox1.SelectionFont = new Font ("Courier", 10, FontStyle.Bold)

 


22.5 How can I change the FontStyle of a selection without losing the styles that are present?


If you visit the selection a character at the time, you can get the current FontStyle and modify it directly to add or remove a style like Bold or Italic. Doing it a character at a time will avoid losing the other styles that are set. The problem with doing it a whole selection at a time is that the FontStyle of the entire selection is the common styles set among all characters in the selection. So, if one char is bold and one is not, then bold is not set when you retrieve the fontstyle for the entire selection. Doing things a character at the time, avoids this problem and allows things to work OK. You can download a working sample(CS,VB).

private void AddFontStyle(FontStyle style)
{
     int start = richTextBox1.SelectionStart;
     int len = richTextBox1.SelectionLength;
     System.Drawing.Font currentFont;
     FontStyle fs;
     for(int i = 0; i < len; ++i)
     {
          richTextBox1.Select(start + i, 1);
          currentFont = richTextBox1.SelectionFont;
          fs = currentFont.Style;
          //add style
          fs = fs | style;
          richTextBox1.SelectionFont = new Font(
               currentFont.FontFamily,
               currentFont.Size,
               fs
               );
     }
}

private void RemoveFontStyle(FontStyle style)
{
     int start = richTextBox1.SelectionStart;
     int len = richTextBox1.SelectionLength;
     System.Drawing.Font currentFont;
     FontStyle fs;
     for(int i = 0; i < len; ++i)
     {
          richTextBox1.Select(start + i, 1);
          currentFont = richTextBox1.SelectionFont;
          fs = currentFont.Style;
          //remove style
          fs = fs & ~style;
          richTextBox1.SelectionFont = new Font(
               currentFont.FontFamily,
               currentFont.Size,
               fs
               );
     }
}

private void button1_Click(object sender, System.EventArgs e)
{
     AddFontStyle(FontStyle.Bold);
}


Here is a suggestion from Nicholas Clark on how to avoid seeing the character by character changes appear as you apply the styles one character at a time in the above code. Create a hidden RTB and store the selected text in it. Then apply the attributes and copy it back into the original richtextbox, so that you don't see the selection changing.


private void change_font(FontStyle style,bool add)
{
richTextBox2.Rtf = richTextBox1.SelectedRtf;
int lengt = richTextBox2.Text.Length;
int length = richTextBox1.SelectionLength;
int start = richTextBox1.SelectionStart;
for (int i = 0; i < lengt; i++) {
richTextBox2.Select(i,1);
Font cfont = richTextBox2.SelectionFont;
FontStyle fs = cfont.Style;
if (add) {
fs = fs | style;
}
else {
fs = fs & ~style;
}
richTextBox2.SelectionFont = new Font(
cfont.FontFamily,
cfont.Size,
fs
);
}
richTextBox2.Select(0,richTextBox2.Text.Length);
richTextBox1.SelectedRtf = richTextBox2.SelectedRtf;
richTextBox1.Select(start,length);
this.richTextBox1.Focus();
isChanged = true;
}


 


22.6 How can I programmatically position the cursor on a given line and character of my richtextbox?


There are a couple different methods that can be used here. The first changes focus, so may not be possible if you have controls that fire validation. The second uses interop, which requires full trust.
Method 1: Eric Terrell suggested this solution in an email to winformsfaq@syncfusion.com.

The richtextbox control contains a Lines array property, one entry for every line. Each line entry has a Length property. With this information, you can position the selection cursor using code such as:

     private void GoToLineAndColumn(RichTextBox RTB, int Line, int Column)
     {
          int offset = 0;
          for (int i = 0; i < Line - 1 && i < RTB.Lines.Length; i++)
          {
               offset += RTB.Lines[i].Length + 1;
          }
          RTB.Focus();
          RTB.Select(offset + Column, 0);
     }

(Note: you may want to store this.ActiveControl to be retrieved after calling Select()).
Method 2:


     const int SB_VERT = 1;
     const int EM_SETSCROLLPOS = 0x0400 + 222;

     [DllImport("user32", CharSet=CharSet.Auto)]
     public static extern bool GetScrollRange(IntPtr hWnd, int nBar, out int lpMinPos, out int lpMaxPos);

     [DllImport("user32", CharSet=CharSet.Auto)]
     public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, POINT lParam);

     [StructLayout(LayoutKind.Sequential)]
     public class POINT
     {
          public int x;
          public int y;

          public POINT()
          {
          }

          public POINT(int x, int y)
          {
               this.x = x;
               this.y = y;
          }
     }

     // Example -- scroll the RTB so the bottom of the text is always visible.
     int min, max;
     GetScrollRange(richTextBox1.Handle, SB_VERT, out min, out max);
     SendMessage(richTextBox1.Handle, EM_SETSCROLLPOS, 0, new POINT(0, max - richTextBox1.Height));


 


22.7 How can I load an embedded rich text file into a richtextbox?


You use the LoadFile method of the RichTextBox, passing it a streamreader based on the resource. So include your RTF file as an embedded resource in your project, say RTFText.rtf. Then load your richtextbox with code such as

     Stream stream = this.GetType().Assembly.GetManifestResourceStream("MyNameSpace.RTFText.rtf");
     if (stream != null)
     {
          StreamReader sr = new StreamReader(stream);
          richTextBox1.LoadFile(stream, RichTextBoxStreamType.RichText);
          sr.Close();
     }

Here is a VB snippet. Depending on your default namespace settings, you may not need explicit reference to the namespace in the GetManifestResourceStream argument.

     Dim stream As Stream = Me.GetType().Assembly.GetManifestResourceStream("MyNameSpace.RTFText.rtf")
     If Not (stream Is Nothing) Then
          Dim sr As New StreamReader(stream)
          richTextBox1.LoadFile(stream, RichTextBoxStreamType.RichText)
          sr.Close()
     End If

 


22.8 How can I print my rich text?


There is no direct support for printing rich text in the .NET Framework. To print it, you can use interop with the SendMessage API and these three messages to do your printing.

EM_SETTARGETDEVICE : specify the target device
EM_FORMATRANGE : format part of a rich edit control's contents for a specific device
EM_DISPLAYBAND : send the output to the device

Here is a link to a MSDN article by Martin Muller that implements this interop solution. Getting WYSIWYG Print Results from a .NET RichTextBox


22.9 Where can I find more information on the RTF specification?


 

This site has a lot of good information on the RTF specification: http://www.dubois.ws/software/RTF/.

 


22.10 How can I add a hyperlink to a RichTextBox control?


To add a hyperlink to the RichTextBox, so that it opens up the link you click on, ensure that DetectUrls property is set to True and call:


[C#]
private void richTextBox1_LinkClicked(object sender, System.Windows.Forms.LinkClickedEventArgs e)
{
System.Diagnostics.Process.Start(e.LinkText);
}

[VB.NET]
Private Sub richTextBox1_LinkClicked(ByVal sender As Object, ByVal e As System.Windows.Forms.LinkClickedEventArgs)
System.Diagnostics.Process.Start(e.LinkText)
End Sub


 

posted on 2007-02-15 11:10  Dragon-China  阅读(1127)  评论(0编辑  收藏  举报