I copied word content to richtextbox without loosing format perfectly, but now I am editing the content in the richtextbox.
Now I want to export the richtextbox content to a word document without losing any formating, in C# using WinForms. How do you do it?
WordApp.ActiveDocument.SaveAsQuickStyleSet("abc.doc");
Range rng = WordApp.ActiveDocument.Range(0, 0);
for (int i = 0; i < _dgvrow.Cells.Count; ++i)
{
// add code to loop thru controls and TypeText into word document
Label lb = (Label)this.Controls["lblfield" + (i+1).ToString()];
rng.Text += lb.Text;
rng.Select();
Control ctrl = this.Controls["txtfield" + (i+1).ToString()];
if(ctrl is RichTextBox)
{
RichTextBox rb = (RichTextBox)ctrl;
rng.Text += rb.Text + Environment.NewLine;
rng.Select();
}
else if (ctrl is TextBox)
{
TextBox rb = (TextBox)ctrl;
rng.Text += rb.Text + Environment.NewLine;
rng.Select();
}
}
The Text property of a RichTextBox just returns plain text. Use the Rtf property to return rtf-formatted text.
Unfortunately, Word does not have a method for inserting RTF text. However you can paste RTF-text from the clipboard
Clipboard.SetText(rb.Rtf, TextDataFormat.Rtf);
rng.Paste()
You want to get the rich text format of your control, not just the plain text.
Replace rb.Text with rb.Rtf.
From MSDN:
The Text property does not return any information about the formatting applied to the contents of the RichTextBox. To get the rich text formatting (RTF) codes, use the Rtf property.
Additionally, if you want to save the rich text format to a file, that's built in:
rb.SaveFile(yourFilePath);
With running look over your say I can suggest which I coded correctly.
Save your coded rich text box with save file method as .rtf or .doc and then open in the microsoft word.
Will not fail.
with regards.
Related
I have string with rft formatted text. I believe th string is correct, because when i enter in in notepad and save as rtf document, it is displayed correctly.
The problem is that the highlight is not applied to the text when i try to pass it to RichTextBox.
Expected result is RichtextBox with grey bold text with highlighted word "PORTS", but i get only bold grey text
Rtf string that I pass to RichTextBox:
"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Segoe UI;}}{\colortbl;\red50\green146\blue255;\red235\green153\blue45;\red105\green105\blue105;}\viewkind0\uc1\pard\sa0\sl276\slmult1\cf0\f0\fs32\lang9\b\cf3\highlight2 PORTS\highlight0 documentation. \cf0\b0\par}"
Rtf string that I save as rtf document:
{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Segoe UI;}}{\colortbl;\red50\green146\blue255;\red235\green153\blue45;\red105\green105\blue105;}\viewkind0\uc1\pard\sa0\sl276\slmult1\cf0\f0\fs32\lang9\b\cf3\highlight2 PORTS\highlight0 documentation. \cf0\b0\par}
Example of rtf string that is displayed correctly(here text is not bald and not grey):
"{\rtf1\ansi\ansicpg1252\deff0\nouicompat\deflang1033{\fonttbl{\f0\fnil\fcharset0 Segoe UI;}}{\colortbl;\red50\green146\blue255;\red235\green153\blue45;\red105\green105\blue105;}\viewkind0\uc1\pard\sa0\sl276\slmult1\cf0\f0\fs30\lang9\highlight2 Port\highlight0 Serial \highlight2 port\highlight0 that uses COM \highlight2 port\highlight0 s\par}"
Method that i use to set string to RithTextBox:
private void UpdateRtf()
{
MemoryStream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(RtfString));
TextRange range = new TextRange(Document.ContentStart, Document.ContentEnd);
range.Load(stream, DataFormats.Rtf);
}
I have a custom RichTextBox that derives from the RichTextBox base class. Its purpose is to display formatted text. However, any Rtf loaded is displayed as simple text without any formatting: font, font-size, font-style etc.
I have tried the following code to load the Rtf: (Note: rtbEx is the extended richtextbox control; RTF is a string containing the Rtf)
Using a file stream:
FileStream tempFile = File.Open(#"C:\RTF.rtf", FileMode.Open);
tempFile.Position = 0;
rtbEx.LoadFile(tempFile, RichTextBoxStreamType.RichText);
tempFile.Close();
Loading from the specified path:
rtbEx.LoadFile(#"C:\Users\Wilbur Omae\Desktop\RTF.rtf", RichTextBoxStreamType.RichText);
Directly setting the Rtf:
rtbEx.Rtf = RTF;
On checking the Rtf of the rtbEx, it seems to be perfect Rtf, yet it is displayed as plain text.
What could be the issue?
Update 1:
The custom RichTextBox is a control within a custom Form which it to be displayed as a TabPage.
you can use Clipboard in this case :
Clipboard.SetText(RichTextBox1.Rtf, TextDataFormat.Rtf);
and paste it
RichTextBox1.Text= Clipboard.GetText()
It works for me .. try it
As a workaround, I ensured the Rtf was set only when the form had been shown by trapping the Form.Shown event as shown below:
public class SermonReader : Form
{
public RichTextBoxEx rtbEx= new RichTextBoxEx();
private string RTF = "";
public SermonReader(string rtf)
{
RTF = rtf;
Shown += new EventHandler(ehFormShown);
FormBorderStyle = FormBorderStyle.None;
TopLevel = false;
Controls.Add(rtbEx);
rtbEx.Dock = DockStyle.Fill;
}
private void ehFormShown(object sender, EventArgs e)
{
rtbEx.Rtf = RTF;
}
}
I don't know why the issue is this complicated but I hope this helps.
Any other solution? Feel free to comment or answer.
I had the same problem with a richtextbox within a winformscontrol
within a dialog (MFC), the rtb should be filled with rtf, but
after setting RichTextBox.Rtf, loading from file or Clipboard it all was unformatted.
I could solved it by using Postmessage in OnInitDialog with UpdataData(FALSE) (Sets RichTextBox.Rtf again)
in the handler. seems as if creation yet was not complete ..
I have the following code to format lines being added to a RichTextBox control:
rtb.SelectionFont = new Font(new FontFamily("Microsoft Sans Serif"), 14, FontStyle.Bold);
rtb.SelectionColor = Color.SteelBlue;
rtb.SelectionAlignment = HorizontalAlignment.Center;
rtb.AppendText("This is the message to display");
rtb.AppendText(Environment.NewLine);
rtb.SelectionFont = new Font(new FontFamily("Microsoft Sans Serif"), 10, FontStyle.Regular);
rtb.SelectionColor = Color.Black;
rtb.SelectionAlignment = HorizontalAlignment.Left;
rtb.AppendText("This is the log message");
It producese the following RTF string:
{\rtf1\ansi\ansicpg1252\deff0\deflang4105{\fonttbl{\f0\fnil Microsoft
Sans Serif;}{\f1\fnil\fcharset0 Microsoft Sans Serif;}} {\colortbl
;\red70\green130\blue180;\red0\green0\blue0;}
\viewkind4\uc1\pard\cf1\b\f0\fs28 This is the message to
display\cf2\b0\fs20\par This is the log message\cf0\f1\fs17\par }
If I save that string with the RTF extension and open the document in WordPad i get the expected result, however in the application the formats are not being applied.
Is there a setting in the control I'm missing?
Thank you,
UPDATE: Modified the code as suggested by LarsTech. Now the alignment
works but the font formatting still does not.
UPDATE: The reason was the location where the code was being run. The user control containing the rich text box has an Initialize
function that is called before the Load event. This was preventing
the formatting from being applied. Once I saved the RTF string to a
local variable and used it in the Load event handler the formatting
works correctly. Marked LarstTech as the answer barbecue his comment
did fix the alignment issue. Thank you All.
You need to add a line break:
rtb.AppendText("This is the message to display");
rtb.AppendText(Environment.NewLine);
and remove your manual line break:
//rtb.AppendText("\r\nThis is the log message");
rtb.AppendText("This is the log message");
The SelectionAlignment needs to be applied after the line break is set. In your code, the line break is happening too late.
rtb.Rtf = //Your rtf string
Alternatively, you can use LoadFile if you are actually loading an RTF file
public void LoadMyFile()
{
// Create an OpenFileDialog to request a file to open.
OpenFileDialog openFile1 = new OpenFileDialog();
// Initialize the OpenFileDialog to look for RTF files.
openFile1.DefaultExt = "*.rtf";
openFile1.Filter = "RTF Files|*.rtf";
// Determine whether the user selected a file from the OpenFileDialog.
if(openFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
openFile1.FileName.Length > 0)
{
// Load the contents of the file into the RichTextBox.
richTextBox1.LoadFile(openFile1.FileName);
}
}
Saving and loading RTF file, below code must work, or open the RTF file manually use the #lll answer LoadMyFile() method.
//Save to rtf file
rtb.SaveFile("e:\\aaaa.rtf");
//or
System.IO.File.WriteAllText( "e:\\aaaa.rtf",rtb.Rtf,System.Text.ASCIIEncoding.ASCII);//without BOM signature.
// end of save to rtf
//Load from rtf file.
rtb.LoadFile("e:\\aaaa.rtf");
//or
rtb.Rtf = System.IO.File.ReadAllText("e:\\aaaa.rtf", System.Text.ASCIIEncoding.ASCII);
//end of load rtf from file
I'm building an MS-Word Add-In for the company where I'm doing my internship.
I already created a new ribbon with lots of SplitButtons and Buttons.
Now what i want to do is when you click one of the buttons a content control will ba added to the word doc.
This works fine for Plain Content Controls. These content controls have tags like "sport/basketball/player/name" which is binded to an element in an XML file.
private void addSimpleContentControl(String tag, String placeholder)
{
try
{
contentControlPlain = Globals.ThisAddIn.Application.ActiveDocument.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlText);
contentControlPlain.Tag = tag;
contentControlPlain.SetPlaceholderText(null, null, placeholder);
}
catch (COMException) { }
}
Now let's talk about my problem.
Some of my elements could be present for more then one time. So what i want to create is a Rich Content control which holds more than one Plain content control.
So i have a SplitButton "player" with buttons like "name","jersey number","position",.....
When one of the underlying buttons is clicked i first check if a rich text control with a specific name already exist.
If not than i make one and add one single Plain content control to it.
Rich content control-> plain text control -> end of Rich content control
So far so good, this all goes fine but from the moment i want to add another plain content control to the rich content control this pops up :
"Plain text controls cannot be inserted around other controls or XML elements"
here is my code to add a plain content control to a rich content control.
private void addContentControlToRich(String tag, String placeholder,String title)
{
Microsoft.Office.Interop.Word.Document doc = Globals.ThisAddIn.Application.ActiveDocument;
foreach (Microsoft.Office.Interop.Word.ContentControl cc in doc.ContentControls)
{
if (cc.Title == title && cc.Type == Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlRichText)
{
try
{
Microsoft.Office.Interop.Word.Range rng = cc.Range;
object oRng = rng;
contentControlPlain = doc.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlText, ref oRng);
contentControlPlain.Tag = tag;
contentControlPlain.SetPlaceholderText(null, null, placeholder);
contentControlPlain.LockContentControl = true;
break;
}
catch (COMException) { }
}
}
}
instead of
contentControlPlain = doc.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlText, ref oRng);
use
contentControlPlain = richTextControl.Range.ContentControls.Add(Microsoft.Office.Interop.Word.WdContentControlType.wdContentControlText, ref oRng);
before using above code use code below
Application.Selection.Start = lastControlinRichTextControl.Range.End+1;
and set `oRng = Application.Selection.Range
As per the message, your code is trying to wrap a plain text control around everything in the rich text control (ie an existing plain text control). Fix your range object so that it doesn't do that eg collapse it to just a point inside the rich text control.
When using the Microsoft RichTextBox control it is possible to add new lines like this...
richtextbox.AppendText(System.Environment.NewLine); // appends \r\n
However, if you now view the generated rtf the \r\n characters are converted to \par not \line
How do I insert a \line control code into the generated RTF?
What does't work:
Token Replacement
Hacks like inserting a token at the end of the string and then replacing it after the fact, so something like this:
string text = "my text";
text = text.Replace("||" "|"); // replace any '|' chars with a double '||' so they aren't confused in the output.
text = text.Replace("\r\n", "_|0|_"); // replace \r\n with a placeholder of |0|
richtextbox.AppendText(text);
string rtf = richtextbox.Rtf;
rtf.Replace("_|0|_", "\\line"); // replace placeholder with \line
rtf.Replace("||", "|"); // set back any || chars to |
This almost worked, it breaks down if you have to support right to left text as the right to left control sequence always ends up in the middle of the placeholder.
Sending Key Messages
public void AppendNewLine()
{
Keys[] keys = new Keys[] {Keys.Shift, Keys.Return};
SendKeys(keys);
}
private void SendKeys(Keys[] keys)
{
foreach(Keys key in keys)
{
SendKeyDown(key);
}
}
private void SendKeyDown(Keys key)
{
user32.SendMessage(this.Handle, Messages.WM_KEYDOWN, (int)key, 0);
}
private void SendKeyUp(Keys key)
{
user32.SendMessage(this.Handle, Messages.WM_KEYUP, (int)key, 0);
}
This also ends up being converted to a \par
Is there a way to post a messaged directly to the msftedit control to insert a control character?
I am totally stumped, any ideas guys? Thanks for your help!
Adding a Unicode "Line Separator" (U+2028) does work as far as my testing showed:
private void Form_Load(object sender, EventArgs e)
{
richText.AppendText("Hello, World!\u2028");
richText.AppendText("Hello, World!\u2028");
string rtf = richText.Rtf;
richText.AppendText(rtf);
}
When I run the program, I get:
Hello, World!
Hello, World!
{\rtf1\ansi\ansicpg1252\deff0\deflang1031{\fonttbl{\f0\fnil\fcharset0 Courier New;}}
{\colortbl ;\red255\green255\blue255;}
\viewkind4\uc1\pard\cf1\f0\fs17 Hello, World!\line Hello, World!\line\par
}
It did add \line instead of \par.
Since you want to use a different RTF code, I think you may need to forget about the simplistic AppendText() method and manipulate the .Rtf property of your RichTextBox directly instead. Here is a sample (tested) to demonstrate:
RichTextBox rtb = new RichTextBox();
//this just gets the textbox to populate its Rtf property... may not be necessary in typical usage
rtb.AppendText("blah");
rtb.Clear();
string rtf = rtb.Rtf;
//exclude the final } and anything after it so we can use Append instead of Insert
StringBuilder richText = new StringBuilder(rtf, 0, rtf.LastIndexOf('}'), rtf.Length /* this capacity should be selected for the specific application */);
for (int i = 0; i < 5; i++)
{
string lineText = "example text" + i;
richText.Append(lineText);
//add a \line and CRLF to separate this line of text from the next one
richText.AppendLine(#"\line");
}
//Add back the final } and newline
richText.AppendLine("}");
System.Diagnostics.Debug.WriteLine("Original RTF data:");
System.Diagnostics.Debug.WriteLine(rtf);
System.Diagnostics.Debug.WriteLine("New Data:");
System.Diagnostics.Debug.WriteLine(richText.ToString());
//Write the RTF data back into the RichTextBox.
//WARNING - .NET will reformat the data to its liking at this point, removing
//any unused colors from the color table and simplifying/standardizing the RTF.
rtb.Rtf = richText.ToString();
//Print out the resulting Rtf data after .NET (potentially) reformats it
System.Diagnostics.Debug.WriteLine("Resulting Data:");
System.Diagnostics.Debug.WriteLine(rtb.Rtf);
Output:
Original RTF data:
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}
\viewkind4\uc1\pard\f0\fs17\par
}
New RTF Data:
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}
\viewkind4\uc1\pard\f0\fs17\par
example text0\line
example text1\line
example text2\line
example text3\line
example text4\line
}
Resulting RTF Data:
{\rtf1\ansi\ansicpg1252\deff0\deflang1033{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}
\viewkind4\uc1\pard\f0\fs17\par
example text0\line example text1\line example text2\line example text3\line example text4\par
}
if you are using paragraphs to write to richtextbox you can use the LineBreak() same code shown below
Paragraph myParagraph = new Paragraph();
FlowDocument myFlowDocument = new FlowDocument();
// Add some Bold text to the paragraph
myParagraph.Inlines.Add(new Bold(new Run(#"Test Description:")));
myParagraph.Inlines.Add(new LineBreak()); // to add a new line use LineBreak()
myParagraph.Inlines.Add(new Run("my text"));
myFlowDocument.Blocks.Add(myParagraph);
myrichtextboxcontrolid.Document = myFlowDocument;
Hope this helps!