rtf to textblock - c#

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");

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();
}
}

c# convert '\n\r' to '&#x13' while saving XDocument

I have searched for solution for this but all I found are questions how to prevent this.
I have a simple code for saving and loading XML.
XDocument xDoc;
public Form1()
{
InitializeComponent();
xDoc = new XDocument(new XElement("root", new XElement("data")));
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
string input = textBox1.Text;
xDoc.Root.SetElementValue("data", input);
rtxtXPreview.Text = xDoc.ToString();
txtValuePreview.Text = xDoc.Root.Element("data").Value;
}
private void button1_Click(object sender, EventArgs e)
{
SaveAndLoad();
}
private void SaveAndLoad()
{
string dataNodeValue;
xDoc.Save(path);
dataNodeValue = xDoc.Descendants("data").First().Value;
txtValuePreview.Text = dataNodeValue;
rtxtXPreview.Text = xDoc.ToString();
}
textBox1: is the input for the data element.
rtxtXPreview: is a rich textbox for displaying the text of the XML.
txtValuePreview: is a textbox for displaying the element value.
The problem is that when I enter value like:
A
B
C
The XML shows fine with the line breaks but once I hit the button the document is saved without those. So when I debugged my code I found that the characters \n\r is replaced with \n so I searched for this problem and found this code:
private void SaveAndLoadFixed()
{
string dataNodeValue;
XmlWriterSettings xmlWriterSettings =
new XmlWriterSettings { NewLineHandling = NewLineHandling.None, Indent = true };
using (XmlWriter xmlWriter = XmlWriter.Create(path, xmlWriterSettings))
{
xDoc.Save(xmlWriter);
xmlWriter.Flush();
}
//xDoc.Save(path);
XElement xDatabaseElement;
using (XmlTextReader xmlTextReader = new XmlTextReader(path) { WhitespaceHandling = WhitespaceHandling.Significant })
{
xmlTextReader.MoveToContent();
xDatabaseElement = XElement.Load(xmlTextReader);
}
dataNodeValue = xDatabaseElement.Descendants("data").First().Value;
txtValuePreview.Text = dataNodeValue;
rtxtXPreview.Text = xDatabaseElement.ToString();
}
This worked fine but why the characters \n\r not replaced with &#x13 because when I tried to type the character < or > it was replaced with < & > respectively ?

how can I save HTML content of HTML editor in c#

I used this code to open the HTML page in HTML editor in c#.
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
using (OpenFileDialog ofd = new OpenFileDialog() { Multiselect =
false, ValidateNames = true, Filter = "HTML|*.html" })
if (ofd.ShowDialog() == DialogResult.OK)
{
textBox1.Text = ofd.FileName;
FileStream fs = new FileStream(ofd.FileName, FileMode.Open, FileAccess.Read);
webBrowser1.DocumentStream = fs;
}
}
and also I used this code to save the changes
private void saveToolStripMenuItem_Click(object sender, EventArgs e)
{
SaveFileDialog svf = new SaveFileDialog();
svf.Filter = "Text Files (.html)|*.html";
if (svf.ShowDialog() == DialogResult.OK)
{
System.IO.StreamWriter sw = new System.IO.StreamWriter(svf.FileName);
sw.WriteLine(webBrowser1);
sw.Close();
}
}
However, the only line is saved in my HTML page is this message: System.Windows.Forms.WebBrowser.
Do you have any idea that how can I save the content of the HTML page? Thanks
The following should work as you require:
System.IO.StreamWriter sw = new System.IO.StreamWriter(svf.FileName);
webBrowser1.DocumentStream.CopyTo(sw.BaseStream);
sw.Flush();
sw.Close();
The reason yours does not work is because you're trying to write an object to a stream directly, which as stated implicitly calls the ToString() method.

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

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);
}
}

How to add events after load back by XamlReader

I created a class Rtb which is to create a new RichTextBox, below is the constructor and list
public Rtb()
{
newRTB = new RichTextBox();
newRTB.IsReadOnly = true;
newRTB.MouseDoubleClick += new MouseButtonEventHandler(newRTB_MouseDoubleClick);
reqName = "Box" + NextID.ToString();
newRTB.Name = reqName;
}
List<Rtb> rtbeditor = new List<Rtb>();
I want to click the menu, add a BlockUIContainer, and a new richtextbox inside the container, see below
private void menuReq_Click(object sender, RoutedEventArgs e)
{
BlockUIContainer newBlockUC = new BlockUIContainer();
newBlockUC.Margin = new Thickness(50, 10, 50,10);
Bigwin.Document.Blocks.Add(newBlockUC); //Bigwin is a big richtextbox
rtbeditor.Add(new Rtb());
Rtb newRichTB = new Rtb();
newBlockUC.Child = newRichTB.newRTB;
}
Then I save it by using XamlWriter, the problem is XamlWriter can not save event, so i have to add the event back when loading it, see below
private void LoadRtfFile(string path)
{
FileStream fs = new FileStream(path, FileMode.Open);
FlowDocument doc = XamlReader.Load(fs) as FlowDocument;
Bigwin.Document = doc;
fs.Close();
foreach (var rtb in rtbeditor)
rtb.MouseDoubleClick += req1_MouseDoubleClick; //add event to every richtextbox
}
But the doubleclick event is not added by this solution, I think the last part of codes has problem. So how to add events to every created richtextbox?
You are subscribing to MouseDoubleClick on Rtb, not on Rtb.newRTB.

Categories

Resources