2012-02-10 18 views
41

Ho del testo in un RichTextBox. Questo testo include tag ad esempio: [@TagName!]. Voglio sostituire questi tag con alcuni dati da un database senza perdere la formattazione (caratteri, colori, immagini, ecc.). Ho creato un metodo:Sostituisci testo in 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(); 
    } 

È abbastanza buono ma rimuove le immagini dal contenuto. So che dovrei usare XamlPackage invece di Xaml ma non riesco a ottenerlo come testo normale. C'è qualche altra soluzione per questo?

Grazie per le risposte. ;)

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

La mia soluzione di lavoro:

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

} 

forse non è la migliore, ma che sta funzionando correttamente.

È stato risolto. Ma non posso pubblicare la soluzione perché è sul server aziendale a cui non posso accedere più.

+0

Penso che tu intenda XMLPackage anziché XML. Dove perdi l'immagine trova una corrispondenza sul nome di dt.Rows [0] [colname]? – Paparazzi

+0

No. dt.Rows [0] [nome_colonna] restituisce solo i nomi delle colonne dal database. Le immagini vengono aggiunte in RichTextBox dall'utente. – arche89

+0

a causa delle voci multiple del colname, avresti bisogno di un loop lì da qualche parte, quindi anche se usassi regex.replace invece di match, dovresti comunque eseguire il looping tra le colonne, e potrebbe finire per eseguire sostituzioni inutili a causa dei dati non ha bisogno di correre Ciò rende questa, a mio avviso, probabilmente la migliore risposta possibile. Ottieni le partite, quindi sostituisci i dati secondo necessità. – Nevyn

risposta

-2

Provare a utilizzare il metodo Regex.Replace. È possibile trovare il riferimento al metodo in MSDN http://msdn.microsoft.com/en-us/library/xwewhkd1.aspx

+7

Wow ... sul serio? Utilizzare Regex per manipolare XML ??? –

+2

Per favore non cercare di indurre in errore le persone con risposte prive di significato – Suits999

1

È possibile utilizzare il motore di Razor a fare quello che vuoi nel template soggetto. È possibile scaricare da nuget (http://www.nuget.org/packages/RazorEngine) e senza alcuna configurazione di installazione è possibile utilizzare la sintassi Razor per fare ciò. Per esempio il modello può essere questo:

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

Nota: thats @ Model.Title e @ Model.Icon provengono da Razor

In realtà io uso RazorEngine a tutti il ​​mio compito di template: -mail, report generazione al volo (rdlc), ecc ...

0

Il Regex che si sta utilizzando è avido quindi corrisponderebbe tutto dall'inizio di un token alla fine di uno successivo. Passa a @"\{0}[a-zA-Z]+?{1}" per una corrispondenza migliore.

Inoltre, l'utilizzo del sovraccarico di Regex.Replace che richiede un lambda sarebbe un codice più pulito.

Problemi correlati