I have a blog that I occasionally post to, but it's a PITA because of the fact that it has it's own WYSIWYG editor and doesn't support Markdown. So I have to switch the WYSIWYG editor to the HTML editor, and of course the HTML is garbled from the WYSIWYG editor.So, I wrote a programme that I can feed Markdown into, and it will let me see what the HTML would be, and a preview of how it would look. It's all very simple.The XAML:<Window x:Class=Markdown_Markup.MainWindow        xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation        xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml        xmlns:d=http://schemas.microsoft.com/expression/blend/2008        xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006        xmlns:local=clr-namespace:Markdown_Markup        mc:Ignorable=d        Title=MainWindow Height=297 Width=474        x:Name=_this>    <Grid>        <Grid.RowDefinitions>            <RowDefinition Height=*/>            <RowDefinition Height=*/>            <RowDefinition Height=*/>        </Grid.RowDefinitions>        <Grid.ColumnDefinitions>            <ColumnDefinition Width=*/>            <ColumnDefinition Width=*/>            <ColumnDefinition Width=*/>        </Grid.ColumnDefinitions>        <StatusBar Height=24 VerticalAlignment=Bottom Grid.ColumnSpan=3 Grid.Row=2/>        <Menu x:Name=menu Height=24 VerticalAlignment=Top Grid.ColumnSpan=3/>        <TextBox x:Name=markdownTextBox Margin=5,50,5,29 TextWrapping=Wrap Grid.RowSpan=3 TextChanged=textBox_TextChanged AcceptsReturn=True AcceptsTab=True/>        <TextBox Margin=5,28,5,5 TextWrapping=Wrap Grid.Column=1 Grid.Row=1 IsReadOnly=True DataContext={Binding ElementName=_this} Text={Binding Path=MarkdownHtml}/>        <TextBox Margin=5,26,5,29 TextWrapping=Wrap Grid.Column=1 Grid.Row=2 IsReadOnly=True DataContext={Binding ElementName=_this} Text={Binding Path=RenderHtml}/>        <TextBox x:Name=styleTextBox Margin=5,50,5,0 TextWrapping=Wrap Grid.Column=1 TextChanged=textBox_TextChanged AcceptsReturn=True AcceptsTab=True/>        <WebBrowser x:Name=renderPreviewBrowser Grid.Column=2 Margin=5,50,5,29 Grid.RowSpan=3 Navigating=renderPreviewBrowser_Navigating />        <Label Content=Markdown Content: HorizontalAlignment=Left Margin=5,24,0,0 VerticalAlignment=Top/>        <Label Content=Additional CSS: Grid.Column=1 HorizontalAlignment=Left Margin=5,24,0,0 VerticalAlignment=Top/>        <Label Content=Markdown HTML: Grid.Column=1 HorizontalAlignment=Left Margin=5,2,0,0 Grid.Row=1 VerticalAlignment=Top/>        <Label Content=Render HTML: Grid.Column=1 HorizontalAlignment=Left Margin=5,0,0,0 Grid.Row=2 VerticalAlignment=Top/>        <Label Content=HTML Preview: Grid.Column=2 HorizontalAlignment=Left Margin=5,24,0,0 VerticalAlignment=Top/>    </Grid></Window>The Code Behind:using MarkdownSharp;using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace Markdown_Markup{    /// <summary>    /// Interaction logic for MainWindow.xaml    /// </summary>    public partial class MainWindow : Window    {        public static readonly DependencyProperty MarkdownHtmlProperty = DependencyProperty.Register(MarkdownHtml, typeof(string), typeof(MainWindow), new UIPropertyMetadata(string.Empty));        public string MarkdownHtml        {            get            {                return (string)GetValue(MarkdownHtmlProperty);            }            set            {                SetValue(MarkdownHtmlProperty, value);            }        }        public static readonly DependencyProperty RenderHtmlProperty = DependencyProperty.Register(RenderHtml, typeof(string), typeof(MainWindow), new UIPropertyMetadata(string.Empty));        public string RenderHtml        {            get            {                return (string)GetValue(RenderHtmlProperty);            }            set            {                SetValue(RenderHtmlProperty, value);            }        }        public MainWindow()        {            InitializeComponent();        }        private void textBox_TextChanged(object sender, TextChangedEventArgs e)        {            var markdown = new Markdown();            var html = markdown.Transform(markdownTextBox.Text);            MarkdownHtml = html;            html = $<html>\r\n\t<head>\r\n\t\t<style>\r\n\t\t\t{styleTextBox.Text}\r\n\t\t</style>\r\n\t</head>\r\n\t<body>\r\n\t\t{html}\r\n\t</body>\r\n</html>;            RenderHtml = html;            renderPreviewBrowser?.NavigateToString(html);        }        private void renderPreviewBrowser_Navigating(object sender, NavigatingCancelEventArgs e)        {            // This prevents links in the page from navigating, this also means we cannot call WebBrowser.Navigate for any browsers with this event.            if (e.Uri != null)            {                e.Cancel = true;            }        }    }}If you're going to run it, you need to install MarkdownSharp from NuGet.
Markdown Markup Markleft Markright Editor
c#;.net;wpf;xaml;markdown
You want to unleash the almighty power of WPF, and bind to a ViewModel; WPF and the Model-View-ViewModel design go completely hand-in-hand, especially if you like your code testable.As it stands the only way to test the application logic is to actually run it and see what happens - that's good for a prototype app, but for an actual real-world app you'll want something a bit more robust.Start with a class, and identify what your view needs - as always, input and output:InputSome Markdown contentSome CSS contentOutputThe resulting HTMLEasy as pie. Your ViewModel could start like this:public class MainWindowViewModel : INotifyPropertyChanged{    private string _markdownContent;    public string MarkdownContent    {        get { return _markdownContent; }        set        {            _markdownContent = value;            OnPropertyChanged();        }    }    private string _cssContent;    public string CssContent    {        get { return _cssContent; }        set        {            _cssContent = value;            OnPropertyChanged();        }    }    private string _htmlContent;    public string HtmlContent    {        get { return _htmlContent; }        set        {            _htmlContent = value;            OnPropertyChanged();        }    }    // todo: INotifyPropertyChanged implementation}How is that used? I'll cheat a little and do this to illustrate:public MainWindow(){    InitializeComponent();    DataContext = new MainWindowViewModel();}private MainWindowViewModel ViewModel{    get { return DataContext As MainWindowViewModel; }}Now your View knows about a ViewModel, and its DataContext is set to an instance of it. You'll probably want a better way to do this though, but that's just to get the ball rolling.The MainWindow's DataContext will now be inherited by everything in the XAML that doesn't override it - get rid of all that DataContext={foobar} markup, you don't need it anymore.Now you can do this (removed fluff for clarity):<TextBox Content={Binding MarkdownContent}/><TextBox Content={Binding CssContent}/>The WebBrowser is a little more fun (involves creating a behavior and an attached property - see the linked SO post), but at the end of the day boils down to this:<WebBrowser local:BrowserBehavior.Html={Binding HtmlContent}/>What does that entail? Whenever the markdown/css changes inside the textboxes, the ViewModel knows, because its setters are running - you have a handle to run your application logic, without writing a single line of code in the View's code-behind! No need to handle TextChanged, and no need to even name any of the controls!Now, you can implement the application logic directly inside the ViewModel class, or better, you can constructor-inject the ViewModel with an object that's solely responsible for that.