41

I have some text in a RichTextBox. This text includes tags eg: [@TagName!]. I want to replace these tags with some data from a database without losing formatting (fonts, colors, image, etc). I've created a method:

 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();
    }

It's quite good but it removes images from content. I know that I should use XamlPackage instead of Xaml but then I can't get it as a plain text. Is there any other solution for this?

Thanks for answers. ;)

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

My working solution:

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

}

Maybe it's not the best but it's working correctly.

It was solved. But I can't post solution because it is on company server which I can't access anymore.

Micha
  • 5,117
  • 8
  • 34
  • 47
Artur Michajluk
  • 1,899
  • 2
  • 16
  • 23
  • I think you mean XMLPackage instead of XML. Where you lose the image does it find a match on colname of dt.Rows[0][colname]? – paparazzo Feb 10 '12 at 14:32
  • No. dt.Rows[0][colname] gives me only columns names from database. Images are add in RichTextBox by user. – Artur Michajluk Feb 12 '12 at 18:01
  • because of the multiple colname entries, you would need a loop in there somewhere, so even if you did use regex.replace instead of match, you would still have to loop across the columns, and may end up running useless replaces because of data that doesn't need running. That makes this, in my opinion, probably the best possible answer. Get the matches, then replace the data as needed. – Nevyn Jul 16 '13 at 13:47

4 Answers4

2

You can use the Razor Engine to do whatever you want in the templating subject. You can download from nuget (http://www.nuget.org/packages/RazorEngine) and without any setup configuration you can use the Razor syntax to do this. For example your template can be this:

<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>

Note: the @Model.Title and @Model.Icon thats come from Razor

Actually i use RazorEngine to all my templating task: Email, Report generation on the fly (rdlc), etc...

Miguel
  • 3,786
  • 2
  • 19
  • 32
0

You can use Aspose.dll. it has full forum / examples and documents Replace Text Based on Regular Expression with aspose.dll

Amin AmiriDarban
  • 2,031
  • 4
  • 24
  • 32
0

The Regex you are using is greedy so would match everything from the start of one token to the end of a following one. Change it to @"\{0}[a-zA-Z]+?{1}" for a better match.

Also, using the overload of Regex.Replace that takes a lambda would be cleaner code.

ChrisF
  • 180
  • 8
-2

Try using Regex.Replace Method. You can find reference to the method in MSDN http://msdn.microsoft.com/en-us/library/xwewhkd1.aspx

Ali
  • 25
  • 2