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í (para que se vea que el Guille también se equivoca jajaja)
Espero que te sea de utilidad. Esa es la idea.
Nos vemos.
Guillermo