使用 Caliburn Micro 将 WebView2 绑定到 ViewModel

Bind WebView2 to ViewModel Using Caliburn Micro

我正在使用她找到的指南作为参考:https://docs.microsoft.com/en-us/microsoft-edge/webview2/gettingstarted/wpf

利用该指南,我能够在我的应用程序中启动 WebView2。现在我试图将代码分离到一个 ViewModel 中,因为我将在该页面上有更多元素。整个应用程序使用 Caliburn Micro。除了 WebView2 本身,我能够将所有内容绑定到 ViewModel。当我 Select Go 按钮时,它指出 WebView 为空。我尝试手动设置 WebView,但这不起作用。

BrowserView.xaml:

    <Button 
            x:Name="ButtonGo" 
            Content="Go"
            />
        <TextBox x:Name = "Addressbar"
                 />
    <wv2:WebView2 x:Name = "WebView"
                  Source="{Binding WebViewSource}"
/>

BrowserViewModel.cs

        private WebView2 _webView;

    public WebView2 WebView
    {
        get 
        {
            return _webView; 
        }
        set 
        {
            _webView = value;
            NotifyOfPropertyChange(() => WebView);
        }
    }

    public string WebViewSource { get; set; } = "http://Google.com";

    private string _addressbar;

    public string Addressbar
    {
        get 
        { 
            return _addressbar; 
        }
        set 
        { 
            _addressbar = value;
            NotifyOfPropertyChange(() => Addressbar);
        }
    }


    public void ButtonGo()
    {
        if (WebView != null && WebView.CoreWebView2 != null)
        {
            WebView.CoreWebView2.Navigate("https://bing.com");
        }
    }

无论我尝试什么,WebView 总是返回 null,我无法更改页面。

视图模型不应该保留对 WebView2 这样的元素的引用。这不是 MVVM,也不是 Caliburn.Micro 的工作方式。视图模型定义 source 属性。

如果您将 TextBlock 属性(您不应该!)添加到视图模型,它也将始终是 null,就像您的 WebView2 属性 是,即使您在 XAML 标记中添加具有相应名称的 TextBlock

恐怕这对一般的 MVVM 和特别是 Caliburn.Micro 来说都没有多大意义。

正如 aepot 评论的那样,删除 Webview 属性 并通知源中的更改解决了该问题。视图的代码现在看起来像这样:

<Button x:Name="ButtonGo" 
        Content="Go"/>
<TextBox x:Name = "Addressbar"/>
<wv2:WebView2 x:Name = "WebView"
              Source="{Binding WebViewSource}"/>

对于 ViewModel:

public string Addressbar
{
   get
   {
      return _addressbar;
   }
   set
   {
      _addressbar = value;
      NotifyOfPropertyChange(() => Addressbar);
   }
}

public void ButtonGo()
{
   WebViewSource = Addressbar;
   NotifyOfPropertyChange(() => WebViewSource);
}