sabato 15 settembre 2007

Un Editor HTML per vb.net

Qualche giorno fa mi sono imbattuto nel seguente problema: dovevo scrivere una applicazione Windows Form che permettesse all'utente di inviare delle email in formato html. Per l'invio delle email nessun problema, qualche problema poteva nascere dal fatto che l'utente dovesse formattarle in html. Mi sarebbe servito quindi un editor html WYSIWYG in quanto gli utenti, per definizione, non conoscono l'html.. Li per li ho pensato che il compito fosse di immediata soluzione, "scarico qualche controllo per vb.net ed il gioco è fatto", mi sono detto. Mi sono messo allora al lavoro cercando in rete qualche cosa che potesse tornare utile al mio scopo, ma la maggior parte dei controlli che ho trovato erano o a pagamento o troppo complicati da riutilizzare. Non mi sono perso d'animo e, rimboccandomi le maniche, ho deciso di fare tutto da me. Una base dalla quale partire l'avevo già, qualche anno fa mi ero infatti cimentato nella scrittura di un editor html per asp.net, dovevo quindi importare questo controllo in vb.net. Ecco come ho risolto il problema: ho utilizzato un controllo WebBrowser da fare puntare alla pagina html contenente l'editor. A questo punto il grosso del lavoro era stato fatto, e anche in pochissimo tempo, per completare l'opera dovevo solo dare un aspetto più gradevole all'editor, questa pagina html conteneva infatti, nella sua parte alta, una toolbar per la formattazione del testo che non si integrava bene con il resto dell'applicazione. Ho deciso allora di lasciare nella pagina html solo il cuore javascript dell'editor e di implementare la bottoniera "all'esterno" del WebBrowser usando due controlli ToolStrip. La comunicazione tra l'interfaccia grafica e il javascript della pagina è stata realizzata attraverso la proprietà ObjectForScripting del controllo WebBrowser. Utilizzando il metodo WebBrowser.Document.InvokeScript è possibile richiamare una procedura javascript definita all'interno del documento html, di contro, si può invocare una procedura vb.net dal javascript utilizzando la sintassi window.external.nomeprocedura.
Ecco uno screenshot dell'editor



Al solito, un esempio vale più di mille parole, a questo link potrete trovare una soluzione contenente il codice sorgente dell'editor html. Per chi volesse saperne di più sulla proprietà ObjectForScripting del controllo WebBrowser ecco il link alla pagina di msdn

7 commenti:

Anonimo ha detto...

ciao
mi potresti dire come faccio a prelevare il codice html dalla pagina?
voglio inserire il codice html generato nel database ma non riesco a recuperarlo.....
grazie

Anonimo ha detto...

Ciao anonimo! Allora.. nella bottoniera dello usercontrol in alto a destra è presente un bottone salva il quale, ogni volta che viene premuto, scatena un evento HtmlSaved che ha tra i suoi parametri l'html generato dallo usercontrol. Lo usercontrol espone pure un metodo GetHtml() che forza l'evento HtmlSaved. Per fare quello che serve basta quindi associare un handler a questo evento, dovresti scrivere qualcosa del genere:

AddHandler mHtmlEditor.HtmlSaved, AddressOf HtmlSaved (subito dopo aver istanziato il mHtmlEditor)

e la procedura HtmlSaved potrebbe essere più o meno così:

Private Sub HtmlSaved(ByVal str_HtmlCode As String, ByVal str_BackgroundColor As String)

MsgBox(str_HtmlCode)
' qui potresti mettere il
' salvataggio della stringa
' str_HtmlCode nel database

End Sub

Spero di essere stato chiaro, altrimenti sono qua, sempre disponibile per ulteriori chiarimenti.. Ciao Alessandro

Anonimo ha detto...

Complimenti per il lavoro svolto, ma non riesco proprio a capire come recuperare il codice Html generato... Grazie.

alessandro vivi ha detto...

Salve! Per sapere come ottenere il codice HTML generato dallo usercontrol puoi leggere la risposta che ho dato al primo commento :-) .Se non dovesse essere sufficientemente chiara sono sempre qui per ulteriori chiarimenti. Ciao

Anonimo ha detto...

Ciao
Complimenti per il modulo.
A me funziona tutto regolarmente, tranne l'inserimento di immagini.
Se inserisco una immagine, la vedo nel documento originale ma se invio l'email l'immagine non viene allegata e nel 'sorgente del messaggio' della email compare un tag tipo questo:
IMG src=3D"C:\Documents and Settings\giovanni\Documenti\Immagini\g_test.jpg"
che è il link all'imagine nel computer di origine!
Qualche idea?
Grazie
Giovanni

alessandro vivi ha detto...

x Giovanni

Il fatto che le immagini non vengano allegate dipende dal modo in cui invii le e-mail. Per allegare le immagini nel corpo della mail come mi sembra di capire tu vorresti fare, dai una occhiata a questo link:
http://www.example-code.com/vbdotnet/mht_emailHtmlString.asp

Ciao Alessandro

Anonimo ha detto...

ho risolto modificando il body prima di inviare l'email con questa funzione che allega le immagini e sostituisce il tag :

Private Function InserisciImmagini(ByVal MyMail As MailMessage) As String
Dim EBody As String = MyMail.Body
Dim PI As Integer = EBody.ToUpper.IndexOf("<IMG")
Dim PF As Integer = 0
Try
Do Until PI <= 0
PF = EBody.IndexOf(">", PI) + 1
'cerco il tag <img ........>
Dim TestoImg As String = EBody.Substring(PI, PF - PI)
'estraggo la parte src="..........."
Dim Regex As Regex = New Regex(".*src=[^""]*""")
Dim PathImg As String = Regex.Replace(TestoImg, "")
Regex = New Regex("file:///")
PathImg = Regex.Replace(PathImg, "")
Regex = New Regex(""">")
PathImg = Regex.Replace(PathImg, "") 'in PathImg adesso ho il path all'immagine
Dim A As System.Net.Mail.Attachment = New System.Net.Mail.Attachment(PathImg) 'aggiungo l'immagine come attachment

Dim RGen As Random = New Random(PI)
A.ContentId = RGen.Next(100000, 9999999).ToString() 'genero un numero casuale per il ContentId e lo attacco
MyMail.Attachments.Add(A)
'sostituisco il tag img con quello nuovo
EBody = EBody.Replace(TestoImg, "<img src='cid:" + A.ContentId + "'>")
PI = EBody.ToUpper.IndexOf("<IMG", PI + 5) 'sposto il punto di ricerca
Loop
MyMail.Body = EBody
Catch ex As Exception
Return ex.Message
End Try
Return "ok"
End Function

Grazie comunque per l'aiuto!
Giovanni