Заменить текст в XamlPackage - PullRequest
41 голосов
/ 10 февраля 2012

У меня есть текст в RichTextBox.Этот текст содержит теги, например: [@TagName!].Я хочу заменить эти теги некоторыми данными из базы данных без потери форматирования (шрифты, цвета, изображения и т. Д.).Я создал метод:

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

}

Возможно, это не лучшее, но работаетправильно.

Это было решено.Но я не могу опубликовать решение, потому что оно находится на сервере компании, к которому я больше не могу получить доступ.

Ответы [ 4 ]

1 голос
/ 25 июля 2013

Вы можете использовать Razor Engine, чтобы делать все, что вы хотите в шаблонной теме.Вы можете скачать с 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.Заголовок и @ Model.Icon, которые исходят от Razor

На самом деле я использую RazorEngine для всех своих шаблонных задач: электронная почта, генерация отчетов на лету (rdlc) и т. Д. *

0 голосов
/ 06 августа 2013

Regex, который вы используете, является жадным, поэтому будет соответствовать всему от начала одного токена до конца следующего.Измените его на @"\{0}[a-zA-Z]+?{1}" для лучшего соответствия.

Также, использование перегрузки Regex.Replace, которая принимает лямбду, будет более чистым кодом.

0 голосов
/ 23 января 2013

Вы можете использовать Aspose.dll. у него есть полный форум / примеры и документы Заменить текст на основе регулярного выражения на aspose.dll

0 голосов
/ 01 августа 2012

Попробуйте использовать метод Regex.Replace.Вы можете найти ссылку на метод в MSDN http://msdn.microsoft.com/en-us/library/xwewhkd1.aspx

...