2012-02-10 1 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, но тогда я не могу получить его как обычный текст. Есть ли другое решение для этого?

Спасибо за ответы. ;)

[EDIT: 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. Где вы теряете изображение, он находит совпадение на colname dt.Rows [0] [colname]? – Paparazzi

+0

№ dt.Rows [0] [colname] дает мне только имена колонок из базы данных. Изображения добавляются в RichTextBox пользователем. – arche89

+0

из-за нескольких записей colname, вам понадобится цикл где-то там, поэтому, даже если вы использовали regex.replace вместо соответствия, вам все равно придется перебирать столбцы и может закончиться бесполезными заменами из-за данных который не нуждается в беге. Это делает это, на мой взгляд, вероятно наилучшим возможным ответом. Получите совпадения, затем замените данные по мере необходимости. – Nevyn

ответ

-2

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

+7

Вау ... серьезно? Использовать Regex для управления XML ??? –

+2

Пожалуйста, не пытайтесь вводить людей в заблуждение бессмысленными ответами – Suits999

1

Вы можете использовать бритву 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.Title и @ Model.Icon то будет исходить от Razor

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

0

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

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