【问题标题】:Fill a Dockpanel with a WPF Webbrowser in MVVM pattern使用 MVVM 模式中的 WPF Webbrowser 填充 Dockpanel
【发布时间】:2015-06-18 20:17:29
【问题描述】:

我想写一个 HTML 编辑器。为此,我想要一个 MenuItem “New”,当它被单击时,它会在 Dockpanel 中打开一个 WPF WebBrowser 控件。从现在开始,我用 CodeBehind 实现了这个功能。所以我的 XML 代码如下所示:

<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>

并且在后面的代码中实现了以下功能:

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";
    }

但是现在我想通过使用 MVVM 模式来分离视图和模型。谁能帮我怎么做?我在理解我的应用程序的 MVVM 模式方面遇到了真正的问题。

感谢您的帮助!

【问题讨论】:

标签: c# wpf mvvm dockpanel


【解决方案1】:

我使用 Command 绑定和 MVVM Light messenger 类处理控件上的方法。为了使其工作,您需要为 WPF 安装 MVVM Light Nuget 包。通过这种方法,MenuItem 上的 Click 事件被绑定到 ViewModel 中的 RelayCommand。该 RelayCommand 广播一条消息(“MakeWebBrowser”),订阅消息服务的任何类都可以访问该消息。 View 代码隐藏订阅消息,接收消息并触发创建 WebBrowser 的方法。

查看:

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

视图模型:

声明 RelayCommand:

RelayCommand MakeWebBrowserCommand
{
   get;
   private set;
}

在您的 ViewModel 构造函数中:

DoSomethingCommand = new RelayCommand(MakeWebBrowserCommandExecute);

定义 MakeWebBrowserCommandExecute 方法:

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

查看代码隐藏:

在 View 的构造函数中,注册 NotificationMessages:

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

定义 NotificationMessageReceived 方法:

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

重命名/定义方法:

private void Neu_Click(object sender, RoutedEventArgs e)

到:

private void MakeWebBrowser()

【讨论】:

  • 如果 Web Browser.Navigate 是一个属性而不是一个方法,我会很适合你。关于如何绑定方法有更好的想法吗?
  • 它在 MenuItem 的原始点击处理程序中,我指出应该重命名它。
  • 这种方法允许您在 View 和 ViewModel 之间保持真正干净的分离,这对于 MVVM 模式非常有用。替代方法包括将 WebBrowser 控件作为 CommandParameter 传递之类的方法,这要容易得多,但肯定会在 View 和 ViewModel 之间创建依赖关系。
猜你喜欢
  • 2011-12-05
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 2016-12-02
  • 2021-05-13
  • 1970-01-01
  • 2010-11-08
  • 1970-01-01
相关资源
最近更新 更多