2012-02-10 52 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會更乾淨的代碼。