The WebBrowser
is a little more fun 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:
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:
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:
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:
Input
- Some Markdown content
- Some CSS content
Output
- The resulting HTML
Easy 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.