Pues eso… que el otro día te puse un ejemplo de Abrir y guardar archivos usando RichTextBox para WPF y anoche haciendo pruebas con vocales acentuadas, me di cuenta que el formato XAML (DataFormats.Xaml) las tildes se las pasaba por el forro… así que… buscando en la red de redes vi un ejemplo que evita eso… o casi, al menos te permite tener la opción de poder hacerlo.
El problema está (o estaba) en que en el ejemplo de donde saqué el código para guardarlo utiliza esto para crear el Stream de salida: Using fStream As New FileStream(_fileName, FileMode.Create) y usando FileStream no se puede indicar la codificación. O yo no sé cómo hacerlo, que todo hay que decirlo
Al abrir el Stream se hace la llamada al método Save del rango (TextRange) y se indica el formato con el que se guardará: range.Save(fStream, formato, True). range.Save precisa de un Stream, pero el ofrecido por StreamWriter, que es el que yo suelo usar para guardar indicando la codificación, no le sirve.
El truco está en guardar primero el contenido del RichTextBox en la memoria (usando MemoryStream) y después pasar ese flujo de caracteres al disco por medio de StreamWriter.
El código final quedaría de la siguiente forma:
''' <summary> ''' Adaptado del ejemplo de la documentación de Microsoft ''' https://docs.microsoft.com/es-es/dotnet/framework/wpf/controls/ ''' richtextbox-overview ''' </summary> Private Function SaveRtfFormat(_fileName As String, richTB As RichTextBox, formato As String) As Boolean Dim range As TextRange Dim guardado As Boolean = False range = New TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd) ' Para guardar con el formato que queramos ' Adaptado de: ' https://social.msdn.microsoft.com/Forums/vstudio/en-US/ ' a9ef25ef-fada-4cbd-a341-f9eb22fb2f48/ ' how-to-save-a-rich-text-into-a-sql-server-database-in-a-wpf-application?forum=wpf Using stream As New MemoryStream Try range.Save(stream, formato, True) Dim buffer = Encoding.UTF8.GetString(stream.ToArray()) Using sw As New StreamWriter(_fileName, False, Encoding.Default) sw.Write(buffer) End Using guardado = True Catch ex As Exception MessageBox.Show("Error el formato no es válido" & vbCrLf & ex.Message, $"Guardar {formato}", MessageBoxButton.OK, MessageBoxImage.Asterisk) End Try End Using 'Using fStream As New FileStream(_fileName, FileMode.Create) ' Try ' range.Save(fStream, formato, True) ' guardado = True ' Catch ex As Exception ' MessageBox.Show("Error el formato no es válido" & vbCrLf & ' ex.Message, ' $"Guardar {formato}", ' MessageBoxButton.OK, ' MessageBoxImage.Asterisk) ' End Try ' fStream.Close() 'End Using Return guardado End Function
Al final de la función tienes (comentado) el código anterior.
/// <summary> /// Adaptado del ejemplo de la documentación de Microsoft /// https://docs.microsoft.com/es-es/dotnet/framework/wpf/controls/ /// richtextbox-overview /// </summary> private bool SaveRtfFormat(string _fileName, RichTextBox richTB, string formato) { TextRange range; bool guardado = false; range = new TextRange(richTB.Document.ContentStart, richTB.Document.ContentEnd); // Para guardar con el formato que queramos // Adaptado de: // https://social.msdn.microsoft.com/Forums/vstudio/en-US/ // a9ef25ef-fada-4cbd-a341-f9eb22fb2f48/ // how-to-save-a-rich-text-into-a-sql-server-database-in-a-wpf-application?forum=wpf using (MemoryStream stream = new MemoryStream()) { try { range.Save(stream, formato, true); var buffer = Encoding.UTF8.GetString(stream.ToArray()); using (StreamWriter sw = new StreamWriter(_fileName, false, Encoding.Default)) { sw.Write(buffer); } guardado = true; } catch (Exception ex) { MessageBox.Show("Error el formato no es válido\r\n" + ex.Message, $"Guardar {formato}", MessageBoxButton.OK, MessageBoxImage.Asterisk); } } // using (FileStream fStream = new FileStream(_fileName, // FileMode.Create)) // { // try // { // range.Save(fStream, formato); // guardado = true; // } // catch (Exception ex) // { // MessageBox.Show("Error el formato no es válido\r\n" + // ex.Message, $"Guardar {formato}", // MessageBoxButton.OK, MessageBoxImage.Asterisk); // } // fStream.Close(); // } return guardado; }
Lo curioso del caso es que si lo guardaba como Rtf (DataFormats.Rtf) las vocales acentuadas se guardaban bien… Pero de esta forma, todo se guarda bien, al menos los tres formatos que he probado: Rtf, Xaml y Text.
Y es que en las pruebas que estaba haciendo usaba el código de ejemplo de la utilidad Compilar y ejecutar y tengo en varios sitios escrita la palabra versión y al guardarlo y después volver a abrirlo con formato Xaml, se mostraba como en la figura 1.
Al principio ni me fijé, pero cuando la ristra esa de caracteres raros se hizo más larga, ya que si me fijé
¡Como para no darme cuenta!
Y ya está… ahora modificaré la entrada anterior o pondré una aclaración para que vengas aquí
Espero que te sea de utilidad. Esa es la idea.
Nos vemos.
Guillermo