c# wpf hyperlink richtextbox

c# - ¿Cómo puedo guardar WPF RichTextBox en databse sin perder enlaces?



hyperlink (1)

Tengo un enlace en Richtextbox y funciona bien, pero si guardo ese Richtextbox en la base de datos y luego lo cargo, ese enlace se eliminará y solo puedo ver el texto de ese enlace.

por ejemplo, mi Richtextbox tiene texto inferior:

Este es un enlace

Pero después de guardar y cargar de nuevo solo puedo ver el texto:

Este es un enlace

El hipervínculo creado dinámicamente a partir del texto seleccionado como abajo:

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;

Guardar el contenido de richtextbox como formato RTF en el campo de texto:

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

Y cargar desde la base de datos al documento de flujo

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


La siguiente muestra parece ser el truco.

Aquí cargo y guardo el XAML lugar del texto en formato rtf. Tenga en cuenta también que debe agregar controladores para los hipervínculos a los elementos después de la carga, ya que no se serializarán.

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