C# 替换XamlPackage中的文本
我在RichTextBox中有一些文本。此文本包括标记,例如:[@TagName!]。我想用数据库中的一些数据替换这些标记,而不会丢失格式(字体、颜色、图像等)。我创建了一个方法:C# 替换XamlPackage中的文本,c#,wpf,string,flowdocument,C#,Wpf,String,Flowdocument,我在RichTextBox中有一些文本。此文本包括标记,例如:[@TagName!]。我想用数据库中的一些数据替换这些标记,而不会丢失格式(字体、颜色、图像等)。我创建了一个方法: void ReplaceTagsWithData(FlowDocument doc) { FileStream fs = new FileStream("tmp.xml", FileMode.Create); TextRange trTextRange =
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();
}
这很好,但它会从内容中删除图像。我知道我应该使用XamlPackage而不是Xaml,但是我不能将它作为纯文本。还有其他解决办法吗
谢谢你的回答
[编辑:13-02-2012 02:14(上午)]
我的工作解决方案:
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);
}
也许这不是最好的,但它工作正常
问题解决了。但我无法发布解决方案,因为它位于我无法再访问的公司服务器上。尝试使用Regex.Replace方法。您可以在MSDN中找到对该方法的引用 您可以使用Aspose.dll。 它有完整的论坛/示例和文档
您可以使用Razor引擎在模板主题中执行任何您想要的操作。您可以从nuget()下载,无需任何设置配置,就可以使用Razor语法来完成此操作。例如,您的模板可以是:
<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>
注意:来自Razor的@Model.Title和@Model.Icon
实际上,我使用RazorEngine来完成所有模板任务:
电子邮件、动态生成报告(rdlc)等。您使用的正则表达式是贪婪的,因此将匹配从一个令牌开始到下一个令牌结束的所有内容。将其更改为
@“\{0}[a-zA-Z]+?{1}”
以获得更好的匹配
另外,使用带有lambda的Regex.Replace重载将是更干净的代码。我认为您指的是XMLPackage而不是XML。在丢失图像的位置,它是否在dt.Rows[0][colname]的colname上找到匹配项?否。dt.Rows[0][colname]只提供数据库中的列名称。图像是用户在RichTextBox中添加的。由于有多个colname条目,您需要在其中的某个位置进行循环,因此即使您使用了regex.replace而不是match,您仍然必须在列之间进行循环,并且可能会因为不需要运行的数据而运行无用的替换。在我看来,这可能是最好的答案。获取匹配项,然后根据需要替换数据。请不要试图用无意义的答案误导人们