How can I save WPF RichTextBox in databse without lost links? - c#

I have a Link in Richtextbox and it works good but if I save that Richtextbox in to database and then load it that link to be deleted and I just can see the text of that Link
for example my Richtextbox have bottom text:
This is a link
But after save and load again I just can see the text:
This is a link
The hyperlink created dynamically from selected text as bellow:
RichTextBox.IsDocumentEnabled = true;
RichTextBox.IsReadOnly = true;
Run run = new Run(RichTextBox.Selection.Text);
Hyperlink hyp = new Hyperlink(run) { TargetName = run.Text };
TERM.WordMain main = new TERM.WordMain();
hyp.Click += new RoutedEventHandler(main.hyperLink_Click);
hyp.NavigateUri = new Uri("http://search.msn.com");
RichTextBox.Cut();
var container = new InlineUIContainer(new TextBlock(hyp), RichTextBox.Selection.Start);
RichTextBox.IsDocumentEnabled = true;
RichTextBox.IsReadOnly = false;
Saving richtextbox content as RTF format to text field:
public static string ToStringFromBytes(System.Windows.Controls.RichTextBox richTextBox)
{
if (richTextBox.Document.Blocks.Count == 0)
{
return null;
}
MemoryStream memoryStream = new MemoryStream();
TextRange textRange = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd);
textRange.Save(memoryStream, System.Windows.DataFormats.Rtf);
return Encoding.UTF8.GetString(memoryStream.ToArray());
}
And load from database to flowdocument
public static FlowDocument LoadFromString(string s)
{
try
{
byte[] byteArray = Encoding.UTF8.GetBytes(s);
MemoryStream stream = new MemoryStream(System.Text.Encoding.UTF8.GetBytes(s));
FlowDocument doc = new FlowDocument();
TextRange textRange = new TextRange(doc.ContentStart, doc.ContentEnd);
textRange.Load(stream, System.Windows.DataFormats.Rtf);
return doc;
}
catch (Exception ex)
{
throw;
}
}

The following sample seems to do the trick.
Here I load and save the XAML instead of the text in rtf format. Note also that you need to add handlers for the hyperlinks back to the elements after loading, since they will not be serialized.
public partial class MainWindow : Window
{
private const string _stateFile = "state.xaml";
public MainWindow()
{
InitializeComponent();
richTextBox.IsReadOnly = false;
}
private void createLinkButton_Click(object sender, RoutedEventArgs e)
{
richTextBox.IsDocumentEnabled = false;
richTextBox.IsReadOnly = true;
var textRange = richTextBox.Selection;
var hyperlink = new Hyperlink(textRange.Start, textRange.End);
hyperlink.TargetName = "value";
hyperlink.NavigateUri = new Uri("http://search.msn.com");
hyperlink.RequestNavigate += HyperlinkOnRequestNavigate;
richTextBox.IsDocumentEnabled = true;
richTextBox.IsReadOnly = false;
}
private void HyperlinkOnRequestNavigate(object sender,
RequestNavigateEventArgs args)
{
// Outputs: "Requesting: http://search.msn.com, target=value"
Console.WriteLine("Requesting: {0}, target={1}", args.Uri, args.Target);
}
private void SaveXamlPackage(string filePath)
{
var range = new TextRange(richTextBox.Document.ContentStart,
richTextBox.Document.ContentEnd);
var fStream = new FileStream(filePath, FileMode.Create);
range.Save(fStream, DataFormats.XamlPackage);
fStream.Close();
}
void LoadXamlPackage(string filePath)
{
if (File.Exists(filePath))
{
var range = new TextRange(richTextBox.Document.ContentStart,
richTextBox.Document.ContentEnd);
var fStream = new FileStream(filePath, FileMode.OpenOrCreate);
range.Load(fStream, DataFormats.XamlPackage);
fStream.Close();
}
// Reapply event handling to hyperlinks after loading, since these are not saved:
foreach (var paragraph in richTextBox.Document.Blocks.OfType<Paragraph>())
{
foreach (var hyperlink in paragraph.Inlines.OfType<Hyperlink>())
{
hyperlink.RequestNavigate += HyperlinkOnRequestNavigate;
}
}
}
private void saveButton_Click(object sender, RoutedEventArgs e)
{
SaveXamlPackage(_stateFile);
}
private void loadButton_Click(object sender, RoutedEventArgs e)
{
LoadXamlPackage(_stateFile);
}
}

Related

How can I write those bytes in this case in C#

I'm new in C#, And I have tried many solutions but couldn't do it, this is my code , How to write this four (bytes) declared in first method but I want write them to file in second method.
private void openfiles()
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Title = "Open";
ofd.Filter = "Bin files|*.bin";
if (ofd.ShowDialog() == DialogResult.OK)
{
string path = ofd.FileName;
using (BinaryReader b = new BinaryReader(File.Open(path, FileMode.Open)))
{
long size = new System.IO.FileInfo(path).Length;
long ssize = new System.IO.FileInfo(path).Length / 1024;
int allsize = unchecked((int)size);
byte[] bytes = b.ReadBytes(4);
}
}
}
private void button2_Click(object sender, EventArgs e)
{
using (BinaryWriter bw =new BinaryWriter(File.Open("FileName.bin",FileMode.Create)))
{
bw.Write(bytes);
bw.Close();
}
}
First you need to have somewhere to store the data after it is read and until it is written again. Best guess would be a field in the form, but that is design decision you need to make.
Next split up your code into functional parts, and don't put everything into button handlers. This way parts of the code can be re-used if needed.
Because the design intent is not clear, I have a very basic skeleton code below:
public partial class Form1 : Form
{
string _filename;
byte[] _data;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var dlg = new OpenFileDialog();
dlg.Title = "Open";
dlg.Filter = "Bin files|*.bin";
if (dlg.ShowDialog() == DialogResult.OK)
{
this._filename = dlg.FileName;
this._data = ReadHeader(_filename);
MessageBox.Show($"Read {_data.Length} bytes from {_filename}");
}
}
private void button2_Click(object sender, EventArgs e)
{
string destination = "Filename.bin";
if (MessageBox.Show($"About to overwrite {destination} with data from {_filename}. Proceed?", "File Header", MessageBoxButtons.YesNo) == DialogResult.Yes)
{
WriteHeader(destination, this._data);
}
}
static byte[] ReadHeader(string filename)
{
byte[] fileHeader;
var fs = File.OpenRead(filename);
using (var fr = new BinaryReader(fs))
{
fileHeader = fr.ReadBytes(4);
}
fs.Close();
return fileHeader;
}
static void WriteHeader(string filename, byte[] fileHeader)
{
var fs = File.OpenWrite(filename);
using (var fw = new BinaryWriter(fs))
{
fw.Write(fileHeader);
}
fs.Close();
}
}

How can I pass images from a dynamically generated image to a specific MS WORD table?

There is a form in which there are text lines, and a flowLayotpanel for accepting dynamically created pictureboxes, please tell me the code for implementing the transfer of images (in this case, from 1 to 3 pieces) to the MS WORD template For text, the transfer is implemented, I can not find a suitable solution for images
example code like this
using DirectShowLib;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using Word = Microsoft.Office.Interop.Word;
private readonly string TemplateFileName = #"D:\BASE\1.docx";
private void btn_scrennshot_Click(object sender, EventArgs e)
{
try
{
if (!Directory.Exists(#"D:\BASE\Images"))
{
Directory.CreateDirectory(#"D:\BASE\Images");
MessageBox.Show("OK");
}
else
{
string path = #"D:\BASE\Images";
pictureBox1.Image.Save(path + #"\" + textBox_3.Text + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second + ".jpeg", ImageFormat.Jpeg);
}
var panel = new TableLayoutPanel();
panel.AutoSize = true;
Mat m = new Mat();
capture.Retrieve(m);
var pb = new PictureBox();
pb.Image = new Bitmap(m.ToImage<Bgr, byte>().Flip(Emgu.CV.CvEnum.FlipType.None).Bitmap);
pb.SizeMode = PictureBoxSizeMode.Zoom;
pb.Name = $"SMV_{textBox_3.Text + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second}";
pb.Height = pb.Image.Height / 10;
pb.Width = pb.Image.Width / 10;
var name = new Label();
name.Text = $"SMV_{textBox_3.Text + DateTime.Now.Hour + DateTime.Now.Minute + DateTime.Now.Second}";
var exportimage_btn = new Button();
exportimage_btn.Text = "Select";
exportimage_btn.Click += Exportimage_btn_Click;
var deleteimage_btn = new Button();
deleteimage_btn.Text = "Delete";
deleteimage_btn.Click += Deleteimage_btn_Click;
panel.Controls.Add(pb);
panel.Controls.Add(name);
panel.Controls.Add(exportimage_btn);
panel.Controls.Add(deleteimage_btn);
flowLayoutPanel1.Controls.Add(panel);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void Deleteimage_btn_Click(object sender, EventArgs e)
{
var deleteButton = (Button)sender;
var tableLayoutPanel = deleteButton.Parent;
var flowLayoutPanel1 = tableLayoutPanel.Parent;
flowLayoutPanel1.Controls.Remove(tableLayoutPanel);
foreach (Control control in tableLayoutPanel.Controls)
control.Dispose();
tableLayoutPanel.Dispose();
}
private void Exportimage_btn_Click(object sender, EventArgs e)
{
var exportButton = (Button)sender;
var tableLayoutPanel = exportButton.Parent;
tableLayoutPanel.Controls.Remove(exportButton);
flowLayoutPanel_images.Controls.Add(tableLayoutPanel);
exportButton.Dispose();
}
private void btn_close_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void btn_export_Click(object sender, EventArgs e)
{
var text1 = textBox_2.Text;
var text2 = textBox_2.Text;
var text3 = textBox_3.Text;
var text4 = textBox_4.Text;
var data1 = dateTimePicker_1.Value.ToShortDateString();
var data2 = dateTimePicker_2.Value.ToShortDateString();
var text5 = textBox_5.Text;
var text6 = textBox_6.Text;
var text7 = comboBox_1.Text;
var text8 = comboBox_2.Text;
var text9 = comboBox_3.Text;
var text10 = comboBox_4.Text;
var text11 = textBox_7.Text;
var text12 = textBox_8.Text;
var text13 = comboBox_5.Text;
var text14 = textBox_9.Text;
//TODO WORD
var wordApp = new Word.Application();
wordApp.Visible = false;
try
{
var wordDocument = wordApp.Documents.Open(TemplateFileName);
ReplaceWordStub("{text1}", text1, wordDocument);
ReplaceWordStub("{text2}", text2, wordDocument);
ReplaceWordStub("{text3}", text3, wordDocument);
ReplaceWordStub("{text4}", text4, wordDocument);
ReplaceWordStub("{data1}", data1 wordDocument);
ReplaceWordStub("{text5}", text5, wordDocument);
ReplaceWordStub("{data2}", data2, wordDocument);
ReplaceWordStub("{text6}", text6, wordDocument);
ReplaceWordStub("{text7}", text7, wordDocument);
ReplaceWordStub("{text8}", text8, wordDocument);
ReplaceWordStub("{text9}", text9, wordDocument);
ReplaceWordStub("{text10}", text10, wordDocument);
ReplaceWordStub("{text11}", text11, wordDocument);
ReplaceWordStub("{text12}", text12, wordDocument);
ReplaceWordStub("{text13}", text13, wordDocument);
ReplaceWordStub("{text14}", text14, wordDocument);
wordDocument.SaveAs2(#"D:\BASE\2.docx");
wordApp.Visible = true;
}
catch
{
MessageBox.Show("Error!");
}
}
private void ReplaceWordStub(string stubToReplace, string text, Word.Document wordDocument)
{
var range = wordDocument.Content;
range.Find.ClearFormatting();
range.Find.Execute(FindText: stubToReplace, ReplaceWith: text);
}
Because I don't have a camera, I use an existing picture to add. Then add it and save it to the folder at the same time, keeping the picture name consistent.
You can modify it according to your actual situation, I'm just doing it as a demonstration.
If you have questions about my code, please add a comment below.
First, add a bookmark in the template:
Use selection to find the bookmark position and start importing pictures.
bk.Select();
Selection sel = wordApp.Selection;
sel.InlineShapes.AddPicture("//path");
Export code:
private void btn_export_Click(object sender, EventArgs e) {
//TODO WORD
var wordApp = new Word.Application();
wordApp.Visible = false;
try {
var wordDocument = wordApp.Documents.Open(TemplateFileName);
//Through the Applicatin property of Document, we can get the Applicatin object in turn.
wordApp = wordDocument.Application;
wordDocument.ActiveWindow.Visible = true;
foreach (Bookmark bk in wordDocument.Bookmarks) {
if (bk.Name == "picture") {
//Use the Selection object to insert a picture
bk.Select();
Selection sel = wordApp.Selection;
//Traverse the big panel to find all the small panels
foreach (Control img in flowLayoutPanel_images.Controls) {
//Traverse the small panel to find the label
foreach (Control label in img.Controls) {
if (label is Label)
//Determine the picture to be added from the folder according to the text of the label
sel.InlineShapes.AddPicture(#"C:/demo/images/" + label.Text + ".png");
}
}
}
}
wordDocument.SaveAs(#"C:/demo/images/2.docx");
wordApp.Quit();
} catch {
MessageBox.Show("Error!");
}
}
Schematic diagram:
word:
app:
Start:
Output:
After:

onChange on dynamically created elements

I created dynamically 2 elements. Now I would like copy data from richTextBox to WebBrowser on event onChange
How can I copy data from richTextBox to WebBrowser when I created it dynamically?
My code
void OpenFile(string path, string filename)
{
StreamReader read = new StreamReader(path);
if(richTextBox1.Text.Length == 0)
{
return;
}
else
{
TabPage tp = new TabPage();
int tc = tabControl1.TabCount + 1;
tp.Text = filename;
tabControl1.TabPages.Add(tp);
RichTextBox rtb = new RichTextBox();
WebBrowser wb = new WebBrowser();
rtb.Width = tp.Width / 2;
rtb.Height = tp.Height;
rtb.TextChanged += new System.EventHandler(setText);
rtb.Text = read.ReadToEnd();
wb.Left = tp.Width / 2;
wb.Width = tp.Width / 2;
wb.Height = tp.Height;
tp.Controls.Add(rtb);
tp.Controls.Add(wb);
return;
}
}
private void setText(object sender, EventArgs e)
{
MessageBox.Show("TEXT CHANGED");
}
Try this
rtb.TextChanged += (s, e) => { wb.DocumentText = rtb.Text; };

queue task listbox c# that loads first item in que and refreshes

Ok, in c# I have tried a number of ways to get a listbox to take the contents of a textfile that is populated by other programs, to list the contents. And if certain conditions are true executes a program based off the contents of the first item in the listbox from the textfile. After the program runs its course it deletes the line of execution from the text file, (and this is where my program doesnt continue) and I want the listbox to refresh or reload the text file, once again loading a program based off the contents of the text files first line.
Now if using a listbox isnt the way to go, I am all ears. I just want to be able to display what is in queue. The rest of my program runs great, just this portion, I can't seem to figure out. I have tried to use FileWatcher, and also bindsource, but perhaps I am doing something wrong. I am very new to c#, so any help is appreciated. If need be I can take snippets of my code and display on here. Thanks.
EDIT: Here is some of my current code. It is very butchered as of current as I have been trying different approaches. I dont have it setup to load anything yet, still trying to get it to update when the textfile changes.
public partial class Form1 : Form
{
private FileSystemWatcher _watcher;
List<string> myList = new List<string>();
public Form1()
{
InitializeComponent();
myList = System.IO.File .ReadLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt").ToList();
BindingSource binding = new BindingSource(myList.ToList(), null);
GPSCOM.DataSource = binding;
_watcher = new FileSystemWatcher();
_watcher.Path = Path.GetDirectoryName("C:\\inetpub\\wwwroot\\imomo");
_watcher.Filter=Path.GetFileName("C:\\inetpub\\wwwroot\\imomo\\Orders.txt");
_watcher.SynchronizingObject = GPSCOM;
_watcher.EnableRaisingEvents = true;
_watcher.Changed += new FileSystemEventHandler(fileSystemWatcher1_Changed);
_watcher.Error += new ErrorEventHandler(GPSCOMerror);
GPSCOM.SelectionMode = SelectionMode.One;
//myList.FirstOrDefault();
if (serialPort.IsOpen)
{
return;
}
else
{
for (; ; )
{
switch ((string)GPSCOM.SelectedItem)
{
case "task1":
var lines = System.IO.File.ReadAllLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt");
System.IO.File.WriteAllLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt", lines.Skip(1).ToArray());
//BindingSource binding = new BindingSource(myList.ToList(), null);
myList = System.IO.File.ReadLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt").ToList();
GPSCOM.DataSource = binding;
GPSCOM.SelectionMode = SelectionMode.One;
myList.FirstOrDefault();
GPSCOM.SetSelected(0, true);
GPSCOM.Refresh();
return;
case "task2":
var lines1 = System.IO.File.ReadAllLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt");
System.IO.File.WriteAllLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt", lines1.Skip(1).ToArray());
//BindingSource binding = new BindingSource(myList.ToList(), null);
myList = System.IO.File.ReadLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt").ToList();
GPSCOM.DataSource = binding;
GPSCOM.SelectionMode = SelectionMode.One;
myList.FirstOrDefault();
GPSCOM.SetSelected(0, true);
GPSCOM.Refresh();
return;
case "Task3":
var lines2 = System.IO.File.ReadAllLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt");
System.IO.File.WriteAllLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt", lines2.Skip(1).ToArray());
//BindingSource binding = new BindingSource(myList.ToList(), null);
myList = System.IO.File.ReadLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt").ToList();
GPSCOM.DataSource = binding;
GPSCOM.SelectionMode = SelectionMode.One;
myList.FirstOrDefault();
GPSCOM.SetSelected(0, true);
GPSCOM.Refresh();
return;
case "":
return;
}
}
}
}
private void GPSCOM_SelectedIndexChanged(object sender, EventArgs e)
{
BindingSource binding = new BindingSource(myList.ToList(), null);
myList = System.IO.File.ReadLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt").ToList();
GPSCOM.DataSource = binding;
GPSCOM.Refresh();
}
private void fileSystemWatcher1_Changed(object sender, FileSystemEventArgs e)
{
BindingSource binding = new BindingSource(myList.ToList(), null);
myList = System.IO.File.ReadLines("C:\\inetpub\\wwwroot\\imomo\\Orders.txt").ToList();
GPSCOM.DataSource = binding;
GPSCOM.Refresh();
}
}
You need something like this?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listBox1.DataSource = TaskQue.GetTasks();
}
private void Execute(object sender, EventArgs e)
{
string task = TaskQue.Pop();
//execute task;
listBox1.DataSource = TaskQue.GetTasks();
}
private void AddTask(object sender, EventArgs e)
{
TaskQue.Push(textBox1.Text);
listBox1.DataSource = TaskQue.GetTasks();
}
}
public class TaskQue
{
public static string txtPath = "C:/a.txt";
public static string Pop()
{
StreamReader sr = new StreamReader(txtPath);
string result = sr.ReadLine();
string remaining = sr.ReadToEnd();
sr.Close();
StreamWriter sw = new StreamWriter(txtPath, false);
sw.Write(remaining);
sw.Close();
return result;
}
public static void Push(string s)
{
StreamWriter sw = new StreamWriter(txtPath, true);
sw.WriteLine(s);
sw.Close();
}
public static IEnumerable<string> GetTasks()
{
return new List<string>(File.ReadLines(txtPath));
}
}

rtf to textblock

When I try to set a textblock with rtf it gives a funny output is there a way to display rtf in a textblock if so how?
private void button1_Click(object sender, RoutedEventArgs e)
{
TextRange tr = new TextRange(richTextBox1.Document.ContentStart,
richTextBox1.Document.ContentEnd);
MemoryStream ms = new MemoryStream();
tr.Save(ms, DataFormats.Rtf);
string rtfText = ASCIIEncoding.Default.GetString(ms.ToArray());
textBlock1.Text = rtfText;
Edit update:
I can do this:
private void button1_Click(object sender, RoutedEventArgs e)
{
TextRange tr = new TextRange(richTextBox1.Document.ContentStart,
richTextBox1.Document.ContentEnd);
MemoryStream ms = new MemoryStream();
tr.Save(ms, DataFormats.Rtf); // does not contain a definition
string rtfText = ASCIIEncoding.Default.GetString(ms.ToArray());
MemoryStream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(rtfText));
this.richTextBox2.Selection.Load(stream, DataFormats.Rtf);
But I really hate the richtextbox is there no other controls that can hold rich text formatting? Or is there a way in which you can tell a certain control to display rtf?
You can't use a TextBlock to display RTF text. But if it's ok to show the text in a FlowDocumentScrollViewer, you could copy it this way:
public MainWindow()
{
InitializeComponent();
richTextBox.Document = new FlowDocument();
flowDocumentScrollViewer.Document = new FlowDocument();
}
private void CopyDocument(FlowDocument source, FlowDocument target)
{
TextRange sourceRange = new TextRange(source.ContentStart, source.ContentEnd);
MemoryStream stream = new MemoryStream();
XamlWriter.Save(sourceRange, stream);
sourceRange.Save(stream, DataFormats.XamlPackage);
TextRange targetRange = new TextRange(target.ContentStart, target.ContentEnd);
targetRange.Load(stream, DataFormats.XamlPackage);
}
private void Button_Click(object sender, RoutedEventArgs e)
{
CopyDocument(richTextBox.Document, flowDocumentScrollViewer.Document);
}
Get an overview of Flow Documents here.
This is going to give you the whole FlowDocument but the good news is that does include the markup. I assume that is what you are looking for
string textMarkUp = System.Windows.Markup.XamlWriter.Save(richTextBox1.Document);
Debug.WriteLine(textMarkUp);
Sample output
<Paragraph>asdfas<Run FontWeight="Bold">adsfasd;lkasdf</Run><Run FontStyle="Italic" FontWeight="Bold">alskjfd</Run></Paragraph>
I needed Text Block because it can expand to contents and we can set wrap as none. I am storing rtf string in database. I added the string to RichTextBlock and then used its document to get the inline.
Dim stream As New IO.MemoryStream(System.Text.ASCIIEncoding.[Default].GetBytes("{\rtf1\ansi\ansicpg1252\deff0\deflang1040{\fonttbl{\f0\fnil\fcharset0 Microsoft Sans Serif;}}{\colortbl ;\red255\green255\blue255;}\viewkind4\uc1\pard\cf1\f0\fs29 RIGO NOTIZIA 1 TESTO TESTO TESTO\fs17\par}"))
Dim RichTextBox1 As New RichTextBox()
RichTextBox1.Selection.Load(stream, DataFormats.Rtf)
Dim pr As New System.Windows.Documents.Paragraph()
pr = RichTextBox1.Document.Blocks(0)
Dim tre As Int32 = pr.Inlines.Count
TextBlock1.Inlines.Add(pr.Inlines(0))
RichTextBox is used just for conversion, final control is FlowDocumentScrollViewer, so I've ended up with slightly simplified function:
public static class FlowDocumentScrollViewerEx
{
static public bool ReadFromFile(this FlowDocumentScrollViewer fDoc, String rtfFilePath)
{
RichTextBox retext = new RichTextBox(); // Just an intermediate class to perform conversion
retext.Document = new FlowDocument();
fDoc.Document = new FlowDocument();
TextRange tr = new TextRange(retext.Document.ContentStart, retext.Document.ContentEnd);
if (!File.Exists(rtfFilePath))
return false;
using (var fs = new FileStream(rtfFilePath, FileMode.OpenOrCreate))
{
tr.Load(fs, DataFormats.Rtf);
fs.Close();
}
MemoryStream ms = new MemoryStream();
System.Windows.Markup.XamlWriter.Save(retext, ms);
tr.Save(ms, DataFormats.XamlPackage);
TextRange flowDocRange = new TextRange(fDoc.Document.ContentStart, fDoc.Document.ContentEnd);
flowDocRange.Load(ms, DataFormats.XamlPackage);
return true;
} //ReadFromFile
} //class FlowDocumentScrollViewerEx
Usage is quite trivial:
flowDocument.ReadFromFile(#"license.rtf");

Categories

Resources