c# wpf string flowdocument

c# - Reemplazar texto en XamlPackage



wpf string (4)

Tengo un texto en un RichTextBox. Este texto incluye etiquetas, por ejemplo: [@TagName!]. Quiero reemplazar estas etiquetas con algunos datos de una base de datos sin perder el formato (fuentes, colores, imágenes, etc.). Creé un método:

void ReplaceTagsWithData(FlowDocument doc) { FileStream fs = new FileStream("tmp.xml", FileMode.Create); TextRange trTextRange = new TextRange(doc.ContentStart, doc.ContentEnd); trTextRange.Save(fs, DataFormats.Xaml); fs.Dispose(); fs.Close(); StreamReader sr = new StreamReader("tmp.xml"); string rtbContent = sr.ReadToEnd(); MatchCollection mColl = Regex.Matches(rtbContent, string.Format(@"/{0}+[a-zA-Z]+{1}", prefix, postfix)); foreach (Match m in mColl) { string colname = m.Value.Substring(prefix.Length, (int)(m.Value.Length - (prefix.Length + postfix.Length))); rtbContent = rtbContent.Replace(m.Value.ToString(), dt.Rows[0][colname].ToString()); } rtbEdit.Document = new FlowDocument( (Section)XamlReader.Load( XmlReader.Create(new StringReader(rtbContent)))); sr.Dispose(); sr.Close(); }

Es bastante bueno, pero elimina imágenes del contenido. Sé que debería usar XamlPackage en lugar de Xaml, pero no puedo obtenerlo como texto sin formato. ¿Hay alguna otra solución para esto?

Gracias por las respuestas. ;)

[EDIT: 13-02-2012 02:14 (am)]

Mi solución de trabajo:

void ReplaceTagsWithData(RichTextBox rtb) { FlowDocument doc = rtb.Document; FileStream fs = new FileStream("tmp", FileMode.Create); TextRange trTextRange = new TextRange(doc.ContentStart, doc.ContentEnd); trTextRange.Save(fs, DataFormats.Rtf); fs.Dispose(); fs.Close(); StreamReader sr = new StreamReader("tmp"); string rtbContent = sr.ReadToEnd(); sr.Dispose(); sr.Close(); MatchCollection mColl = Regex.Matches(rtbContent, string.Format(@"/{0}+[a-zA-Z]+{1}", prefix, postfix)); foreach (Match m in mColl) { string colname = m.Value.Substring(prefix.Length, (int)(m.Value.Length - (prefix.Length + postfix.Length))); rtbContent = rtbContent.Replace(m.Value.ToString(), dt.Rows[0][colname].ToString()); } MemoryStream stream = new MemoryStream(ASCIIEncoding.Default.GetBytes(rtbContent)); rtb.SelectAll(); rtb.Selection.Load(stream, DataFormats.Rtf); }

Tal vez no sea el mejor, pero está funcionando correctamente.

Fue resuelto Pero no puedo publicar la solución porque está en el servidor de la compañía al que ya no puedo acceder.



La Regex que está usando es codiciosa, por lo que coincidiría con todo, desde el inicio de un token hasta el siguiente. Cámbielo a @"/{0}[a-zA-Z]+?{1}" para una mejor coincidencia.

Además, usar la sobrecarga de Regex.Replace que toma una lambda sería un código más limpio.


Puede usar el Razor Engine para hacer lo que desee en el tema de plantillas. Puede descargar desde nuget ( http://www.nuget.org/packages/RazorEngine ) y sin ninguna configuración de configuración puede usar la sintaxis de Razor para hacer esto. Por ejemplo, su plantilla puede ser esta:

<Window x:Class="<class>" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="@Model.Title" Icon="@Model.Icon"> <Grid> </Grid> </Window>

Nota: @ Model.Title y @ Model.Icon provienen de Razor

En realidad, uso RazorEngine para todas mis tareas de creación de plantillas: correo electrónico, generación de informes sobre la marcha (rdlc), etc.