0

I want to write an HTML Editor. For this I want to have a MenuItem "New", which opens a WPF WebBrowser Control in a Dockpanel when it is clicked. Since now, I implement this function with CodeBehind. So my XML Code looks like this:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="661.94" Width="781.716">

    <DockPanel x:Name="DockPanel1" HorizontalAlignment="Left" Height="629" 
               LastChildFill="False" VerticalAlignment="Top" Width="772">
        <Menu DockPanel.Dock="Top" HorizontalAlignment="Right" Width="772">
            <MenuItem Header="_Webseite">
                <MenuItem Header="_Neu" Click="Neu_Click" />
                <MenuItem Header="_Öffnen" Click="Oeffnen_Click"/>
                <MenuItem Header="_Speichern" Click="Speichern_Click"/>
                <Separator HorizontalAlignment="Left" Width="145"/>
                <MenuItem Header="_Schließen" HorizontalAlignment="Left" Width="145"/>
            </MenuItem>
            <MenuItem Header="_Tools">
                <MenuItem Header="_Button" Click="Select_Button"> </MenuItem>
            </MenuItem>
        </Menu>
        <StackPanel></StackPanel>
    </DockPanel>

And in the Code behind there is the following function implemented:

public partial class MainWindow : Window
{
    public static IHTMLDocument2 doc;
    public volatile WebBrowser webBrowser;

    public MainWindow()
    {
        InitializeComponent();
    }

    private void Neu_Click(object sender, RoutedEventArgs e)
    {
        // create new WebBrowser for editing
        webBrowser = new WebBrowser();
        DockPanel.SetDock(webBrowser, Dock.Top);
        this.DockPanel1.Children.Add(webBrowser);

        string text = "<html><body></body></html>";
        File.WriteAllText(@"C:\tmp\file.html", text);
        webBrowser.Navigate("file:///C:/tmp/file.html");
        doc = webBrowser.Document as IHTMLDocument2;
        doc.designMode = "On";
    }

But now I want to separate the View and the Model by using the MVVM pattern. Can anyone help me how to do it? I have real problems to understand the MVVM pattern with my Application.

Thanks for helping!

helb
  • 7,609
  • 8
  • 36
  • 58
tutor_girl
  • 7
  • 1
  • 4
  • 2
    I would recommend using Caliburn Micro for your App if you want to use MVVM – jle Apr 13 '15 at 14:07
  • Something like this can be useful http://stackoverflow.com/questions/263551/databind-the-source-property-of-the-webbrowser-in-wpf – Mare Infinitus Apr 13 '15 at 14:29

1 Answers1

1

I handle methods on Controls with Command binding and the MVVM Light messenger class. In order for this to work you'll need to install the MVVM Light Nuget packages for WPF. With this approach the Click event on your MenuItem is bound to a RelayCommand in the ViewModel. That RelayCommand broadcasts a message ("MakeWebBrowser") which is accessible by any class subscribed to the messaging service. The View codebehind is subscribed to messaging, receives the message and fires the method that makes your WebBrowser.

View:

<MenuItem Header="_Neu" Command="{Binding MakeWebBrowserCommand}" />

ViewModel:

Declare the RelayCommand:

RelayCommand MakeWebBrowserCommand
{
   get;
   private set;
}

In your ViewModel constructor:

DoSomethingCommand = new RelayCommand(MakeWebBrowserCommandExecute);

Define the MakeWebBrowserCommandExecutemethod:

private void MakeWebBrowserCommandExecute()
{
    Messenger.Default.Send(new NotificationMessage("MakeWebBrowser"));
}

View codebehind:

In your View's constructor, register for NotificationMessages:

Messenger.Default.Register<NotificationMessage>(this, NotificationMessageReceived);

Define the NotificationMessageReceived method:

private void NotificationMessageReceived(NotificationMessage msg)
{
    if (msg.Notification == "MakeWebBrowser")
            MakeWebBrowser();
}

Rename/define the method:

private void Neu_Click(object sender, RoutedEventArgs e)

to:

private void MakeWebBrowser()
goobering
  • 1,547
  • 2
  • 10
  • 24
  • If Web Browser.Navigate were a property and not a method I'd be right with you. Any better ideas on how to bind a method? – goobering Apr 13 '15 at 14:23
  • It's in the original click handler for the MenuItem, which I indicated should be renamed. – goobering Apr 13 '15 at 14:26
  • This approach allows you to keep a *really* clean separation between View and ViewModel which is great for the MVVM pattern. Alternative approaches include things like passing the WebBrowser control as a CommandParameter, which is significantly easier but definitely creates a dependency between View and ViewModel. – goobering Apr 13 '15 at 15:45