<p>We are looking for a WYSIWYG editor control for our windows application (vb.net or c#) so that users can design HTML emails (to send using the SMTP objects in the dot net framework) before sending.</p>

<p>Currently all the available editors we can find have one of the following issues:</p>

<ol>
<li><p>They rely on mshtml.dll or the web browser control which as proven for us to be unreliable as the HTML code and the editor get out of sync under windows 2000  (IE6)</p></li>
<li><p>They are web-based, not a windows form control     </p></li>
<li><p>They place styles in the head of the document (see note below)</p></li>
</ol>

<p>Unfortunately, as this <a href="http://www.xavierfrenette.com/articles/css-support-in-webmail/" rel="nofollow noreferrer">HTML email article</a> descries the only sure way of making HTML emails to work with styles is to use them inline which now seems to be unsupported in many editors.</p>

<p>Does anyone have any experience in this or could suggest a solution?</p>

[{'answer_id': 8610, 'author': 'Yaakov Ellis', 'author_id': 51, 'author_profile': 'https://Stackoverflow.com/users/51', 'pm_score': 2, 'selected': False, 'text': '<p>I also needed a WYSIWYG editor for a Windows Forms project that I was working on. I wrote about the items that I found <a href="http://ellisweb.net/2007/03/wysiwyg-editing-of-html-in-a-windows-forms-control/" rel="nofollow noreferrer">here</a>. Eventually, I ended up using something that I found on CodeProject: <a href="http://www.codeproject.com/KB/edit/editor_in_windows_forms.aspx" rel="nofollow noreferrer">A Windows Forms based text editor with HTML output</a>. This does violate (a) above in that it uses the WebBrowser control. However, I couldn\'t find anything good that didn\'t do this (if you don\'t use the WebBrowser in some way, then you basically have to write your own HTML parser and renderer in order to handle the "What-You-See" part of WYSIWYG). The good thing about this control is that the source is easily customizable, so you can take away and add formatting options as you need (and if you want the styles to all be in-line, you can do this as well). </p>\n'}, {'answer_id': 9045, 'author': 'J Wynia', 'author_id': 1124, 'author_profile': 'https://Stackoverflow.com/users/1124', 'pm_score': 2, 'selected': False, 'text': '<p>I\'ve been using <a href="http://www.itwriting.com/htmleditor/" rel="nofollow noreferrer">this one</a>, which goes a little lower than the WebBrowser, but still uses MSHTML, which does spit out some ugly HTML. For my purposes, I am doing a multi-tabbed editor with WYSIWYG and HTML edit mode (using <a href="http://sharpdevelop.net/OpenSource/SD/" rel="nofollow noreferrer">ICSharp.TextEditor</a>)  with a Buffer class to update whenever tabs change. As part of that Buffer class, I actually <a href="http://www.wynia.org/wordpress/2008/02/14/using-htmltidy-to-clean-up-html-with-c/" rel="nofollow noreferrer">run the HTML through HTML Tidy</a> and a few scrub-n-replace bits to get valid XHTML.</p>\n\n<p>I only offer that as a solution because I, too, failed to find one that wasn\'t derived from MSHTML in some way and eventually just went ahead with the above solution to keep moving forward.</p>\n'}, {'answer_id': 3263136, 'author': 'Anax', 'author_id': 180243, 'author_profile': 'https://Stackoverflow.com/users/180243', 'pm_score': 1, 'selected': False, 'text': '<p>Instead of searching for an HTML editor, consider the option of a RichText editor (which can be much easier to create) and then convert the final text into a HTML document.</p>\n\n<p>Provided you are required to use a minimal set of features (bold / italics etc) both the creation of the RT editor and the conversion of the final document into HTML format shouldn\'t be hard.</p>\n\n<p>If, on the other hand, you need to use more features (such as tables), you need to study the <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=DD422B8D-FF06-4207-B476-6B5396A18A2B&amp;displaylang=en" rel="nofollow noreferrer">Rich Text Format</a> and implement the features you need.</p>\n\n<p>Additional resources:</p>\n\n<ul>\n<li>Converting RTF to HTML: <a href="http://www.codeproject.com/KB/vb/RTFToHTML.aspx" rel="nofollow noreferrer">http://www.codeproject.com/KB/vb/RTFToHTML.aspx</a></li>\n<li>RichTextBox tips and tricks: <a href="http://www.vbforums.com/showthread.php?t=355994" rel="nofollow noreferrer">http://www.vbforums.com/showthread.php?t=355994</a></li>\n</ul>\n'}, {'answer_id': 21809140, 'author': 'VampireKode', 'author_id': 3315510, 'author_profile': 'https://Stackoverflow.com/users/3315510', 'pm_score': 1, 'selected': False, 'text': '<p>It\'s my first contribution.</p>\n\n<p>You can use a RichTextBox. The RTF format is more than enough to create emails. </p>\n\n<p>I recently wrote about how to load and save to hard disk, the contents of a RichTextBox. </p>\n\n<p>Allows Copy and Paste. It\'s simple to use and with few buttons you can create your own commands.  </p>\n\n<pre><code>With RichTextBox1 \n\xa0\xa0\xa0 .SelStart = 0 \n\xa0\xa0\xa0\xa0.SelLength = Len (. Text) \n\xa0\xa0\xa0\xa0.SelColor = vbRed\nEnd With\n</code></pre>\n\n<p>Example for loading and saving.</p>\n\n<p><a href="http://danielcatala.wordpress.com/2014/01/30/como-cargar-y-guardar-archivos-richtext-con-wpf/" rel="nofollow">http://danielcatala.wordpress.com/2014/01/30/como-cargar-y-guardar-archivos-richtext-con-wpf/</a></p>\n\n<pre><code>Private Sub btnCarga(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click\n\n    Dim archivoCarga As New StreamReader("prueba.rtf")\n    With RichTextBox1\n        .Selection.Select(.Document.ContentStart, RichTextBox1.Document.ContentEnd)\n        .Selection.Load(archivoCarga.BaseStream, System.Windows.DataFormats.Rtf)\n    End With\nEnd Sub\n\nPrivate Sub btnGuarda(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button2.Click\n\n    Dim archivoSalida As New StreamWriter("prueba.rtf")\n    Dim bs As Stream = archivoSalida.BaseStream\n\n    With RichTextBox1\n        .Selection.Select(RichTextBox1.Document.ContentStart,     RichTextBox1.Document.ContentEnd)\n        .Selection.Save(bs, System.Windows.DataFormats.Rtf)\n    End With\nEnd Sub\n</code></pre>\n'}, {'answer_id': 59119227, 'author': 'Reza Aghaei', 'author_id': 3110834, 'author_profile': 'https://Stackoverflow.com/users/3110834', 'pm_score': 2, 'selected': False, 'text': '<p>The simplest HTML editor in Windows Forms could be showing a <code>&lt;div contenteditable="true"&gt;&lt;/div&gt;</code> in a <code>WebBrowser</code> control. It has built in support for common html text editing features like:</p>\n\n<ul>\n<li><kbd>Ctrl</kbd>+<kbd>B</kbd> to make the selection bold</li>\n<li><kbd>Ctrl</kbd>+<kbd>I</kbd> to make the selection italic</li>\n<li><kbd>Ctrl</kbd>+<kbd>U</kbd> to make the selection underlined </li>\n<li><kbd>Ctrl</kbd>+<kbd>A</kbd> to select all text</li>\n<li><kbd>Ctrl</kbd>+<kbd>C</kbd> to copy selection </li>\n<li><kbd>Ctrl</kbd>+<kbd>X</kbd> to cut selection</li>\n<li><kbd>Ctrl</kbd>+<kbd>V</kbd> to paste the selection</li>\n<li><kbd>Ctrl</kbd>+<kbd>K</kbd> to insert a link</li>\n</ul>\n\n<p>However for a better user experience you can rely on DOM <code>document</code> object in <code>WebBrower</code> and use its <a href="https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand" rel="nofollow noreferrer"><code>execCommand</code></a> method and easily run commands like <code>Bold</code>, <code>Italic</code>, <code>Underline</code>, <code>InsertOrderedList</code>, <code>InsertUnorderedList</code>, <code>InsertImage</code>, <code>FormatBlock</code>, <code>ForeColor</code>, <code>BackColor</code>, and etc. </p>\n\n<p>For example the following command inserts ordered list:</p>\n\n<pre><code>webBrowser1.Document.ExecCommand("InsertOrderedList", false, null);\n</code></pre>\n\n<p><strong>Examlpe - Windows Forms HTML Editor</strong></p>\n\n<p>Here I will share an example for a C# application and will show you easily you can implement an HTML editor.</p>\n\n<p><a href="https://i.stack.imgur.com/UmYhp.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UmYhp.png" alt="enter image description here"></a></p>\n\n<pre><code>public class HtmlEditor\n{\n    WebBrowser webBrowser;\n    private dynamic doc;\n    private dynamic contentDiv;\n    public HtmlEditor(WebBrowser webBrowserControl, string htmlContent)\n    {\n        webBrowser = webBrowserControl;\n        webBrowser.DocumentText = @"&lt;div contenteditable=""true""&gt;&lt;/div&gt;";\n        webBrowser.DocumentCompleted += (s, e) =&gt;\n        {\n            doc = webBrowser.Document.DomDocument;\n            contentDiv = doc.getElementsByTagName("div")[0];\n            contentDiv.innerHtml = htmlContent;\n        };\n    }\n    public string HtmlContent =&gt; contentDiv.InnerHtml;\n    public void Bold() { doc.execCommand("bold", false, null); }\n    public void Italic() { doc.execCommand("italic", false, null); }\n    public void Underline() { doc.execCommand("underline", false, null); }\n    public void OrderedList() { doc.execCommand("insertOrderedList", false, null); }\n    public void UnorderedList() { doc.execCommand("insertUnOrderedList", false, null); }\n    public void ForeColor(Color color)\n    {\n        doc.execCommand("foreColor", false, ColorTranslator.ToHtml(color));\n    }\n    public void BackColor(Color color)\n    {\n        doc.execCommand("backColor", false, ColorTranslator.ToHtml(color));\n    }\n    public void InsertImage(Image image)\n    {\n        var bytes = (byte[])new ImageConverter().ConvertTo(image, typeof(byte[]));\n        var src = $"data:image/png;base64,{Convert.ToBase64String(bytes)}";\n        doc.execCommand("insertImage", false, src);\n    }\n    public void Heading(Headings heading)\n    {\n        doc.execCommand("formatBlock", false, $"&lt;{heading}&gt;");\n    }\n    public enum Headings { H1, H2, H3, H4, H5, H6 }\n}\n</code></pre>\n\n<p>To use this HTML Editor class, it\'s enough to have a <code>WebBrowser</code> control on a <code>Form</code> and initialize the editor this way:</p>\n\n<pre><code>HtmlEditor editor;\nprivate void Form1_Load(object sender, EventArgs e)\n{\n    var html = @"Some html content";\n    editor = new HtmlEditor(webBrowser1, html);\n}\n</code></pre>\n\n<p>Then you can use a <code>ToolStrip</code> to show available commands and run the commands. For example:</p>\n\n<pre><code>private void OrderedListButton_Click(object sender, EventArgs e)\n{\n    editor.OrderedList();\n}\n\nprivate void ImageButton_Click(object sender, EventArgs e)\n{\n    using (var ofd = new OpenFileDialog())\n    {\n        ofd.Filter = "Image files|*.png;*.jpg;*.gif;*.jpeg;*.bmp";\n        if (ofd.ShowDialog() == DialogResult.OK)\n        {\n            using (var image = Image.FromFile(ofd.FileName))\n            {\n                editor.InsertImage(image);\n            }\n        }\n    }\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/8604', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/33/']