是否有一种MVVM友好的方式在WPF中使用WebBrowser控件?

dev*_*xer 11 data-binding wpf xaml webbrowser-control mvvm

感谢这个问题(点击我!),我的绑定Source属性WebBrowser正确到我的ViewModel.

现在我想实现两个目标:

  1. 获取IsEnabled我的后退和前进按钮的属性以正确绑定到CanGoBack和的CanGoForward属性WebBrowser.
  2. 弄清楚如何在不使用代码隐藏且没有ViewModel必须知道的情况下调用GoForward()GoBack()方法WebBrowser.

我现在有以下(非工作)XAML标记:

<WebBrowser
    x:Name="_instructionsWebBrowser"
    x:FieldModifier="private"
    clwm:WebBrowserUtility.AttachedSource="{Binding InstructionsSource}" />

<Button
    Style="{StaticResource Button_Style}"
    Grid.Column="2"
    IsEnabled="{Binding ElementName=_instructionsWebBrowser, Path=CanGoBack}"
    Command="{Binding GoBackCommand}"
    Content="&lt; Back" />

<Button
    Style="{StaticResource Button_Style}"
    Grid.Column="4"
    IsEnabled="{Binding ElementName=_instructionsWebBrowser, Path=CanGoForward}"
    Command="{Binding GoForwardCommand}"
    Content="Forward &gt;" />
Run Code Online (Sandbox Code Playgroud)

我很确定问题是CanGoBack并且CanGoForward不是依赖属性(并且没有实现INotifyChanged),但我不太确定如何解决这个问题.

问题:

  1. 有什么办法挂钩的附加属性(像我一样用Source)或类似的东西来获取CanGoBackCanGoForward绑定工作?

  2. 怎么写GoBackCommand,GoForwardCommand所以他们独立于代码隐藏和ViewModel,可以在标记中声明?

Pat*_*ars 5

对于遇到此问题并想要完整解决方案的任何人,这里是。它结合了此线程和链接线程(以及其他链接)中提出的所有建议。

XAML:http : //pastebin.com/aED9pvW8

C# 类:http : //pastebin.com/n6cW9ZBB

XAML 用法示例:http : //pastebin.com/JpuNrFq8

注意:该示例假设您的视图绑定到为浏览器提供源 URL 的 ViewModel。提供了一个非常简陋的导航栏,带有后退、前进和刷新按钮以及地址栏,仅用于演示。

享受。我已将这些 pastebin 的到期时间设置为从不,因此只要 pastebin 存在,它们就应该可用。


Bot*_*000 4

我在可绑定的网络浏览器包装器中使用了它:

    CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseBack, BrowseBack, CanBrowseBack));
    CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseForward, BrowseForward, CanBrowseForward));
    CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseHome, GoHome, TrueCanExecute));
    CommandBindings.Add(new CommandBinding(NavigationCommands.Refresh, Refresh, TrueCanExecute));
    CommandBindings.Add(new CommandBinding(NavigationCommands.BrowseStop, Stop, TrueCanExecute));
Run Code Online (Sandbox Code Playgroud)

请注意,我将可绑定的 Web 浏览器创建为 FrameworkElement,它公开 DependencyProperties 并调用实际浏览器元素上的方法,因此我可以在其上设置 CommandBindings。

这样,您就可以在视图中使用默认的导航命令。使用的处理程序是:

private void CanBrowseBack(object sender, CanExecuteRoutedEventArgs e) {
    e.CanExecute = webBrowser.CanGoBack;
}

private void BrowseBack(object sender, ExecutedRoutedEventArgs e) {
    webBrowser.GoBack();
}

private void CanBrowseForward(object sender, CanExecuteRoutedEventArgs e) {
    e.CanExecute = webBrowser.CanGoForward;
}

private void BrowseForward(object sender, ExecutedRoutedEventArgs e) {
    webBrowser.GoForward();
}

private void TrueCanExecute(object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; }

private void Refresh(object sender, ExecutedRoutedEventArgs e) {
    try { webBrowser.Refresh(); }
    catch (Exception ex) { PmsLog.LogException(ex, true); }
}

private void Stop(object sender, ExecutedRoutedEventArgs e) {
    mshtml.IHTMLDocument2 doc = WebBrowser.Document as mshtml.IHTMLDocument2;
    if (doc != null)
        doc.execCommand("Stop", true, null);
}
private void GoHome(object sender, ExecutedRoutedEventArgs e) {
    Source = new Uri(Home);
}
Run Code Online (Sandbox Code Playgroud)