2012-02-10 50 views
41

我在RichTextBox中有一些文本。此文本包含标签,例如:[@TagName!]。我想用数据库中的某些数据替换这些标记而不会丢失格式(字体,颜色,图像等)。我创建了一个方法:替换XamlPackage中的文本

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 2时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); 

} 

也许这不是最好的,但它的正常工作。

它被解决了。但是我无法发布解决方案,因为它在公司服务器上,我无法访问。

+0

我想你是指XMLPackage而不是XML。你丢失图像的地方是否在dt.Rows [0] [colname]的colname上找到匹配项? – Paparazzi 2012-02-10 14:32:16

+0

No. dt.Rows [0] [colname]仅给出数据库中的列名称。用户将图像添加到RichTextBox中。 – arche89 2012-02-12 18:01:41

+0

由于存在多个colname条目,因此您需要在某处存在循环,因此即使您使用regex.replace而不是match,仍需要跨列循环,并且可能因为数据而最终运行无用的替换那不需要跑步。这在我看来可能是最好的答案。获取匹配,然后根据需要替换数据。 – Nevyn 2013-07-16 13:47:17

回答

1

您可以使用剃刀引擎做任何你想要的模板主题。您可以从nuget下载(http://www.nuget.org/packages/RazorEngine),并且在没有任何设置配置的情况下,您可以使用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> 

注:@ Model.Title和@ Model.Icon这就是来自剃刀

其实我用RazorEngine我所有的模板任务: 电子邮件,报表生成(rdlc)等...

0

正在使用的正则表达式是贪婪的,所以会匹配从一个标记开始到下一个结束的所有内容。将其更改为@"\{0}[a-zA-Z]+?{1}"以获得更好的匹配。

此外,使用Regex.Replace的重载需要一个lambda会更干净的代码。