如何拦截 ViewModel 中的 WebView Navigating 事件

How to intercept WebView Navigating event in ViewModel

我的应用程序有一个 WebView 用于显示一些联系信息。它有一个 link 到我想使用 Device.OpenUri() 从外部加载的网站。我正在使用 FreshMvvm,我想在 ViewModel 中拦截来自 WebView 的 Navigating 事件,并取消将外部页面加载到 WebView 的默认操作。

我试过使用 Corcav.Behaviors 插件,它会调用我的 ViewModel 命令:

        <WebView
            HorizontalOptions="Fill" 
            VerticalOptions="FillAndExpand" 
            Source="{Binding WebViewSource}">
              <b:Interaction.Behaviors>
                <b:BehaviorCollection>
                    <b:EventToCommand
                        EventName="Navigating"
                        Command="{Binding NavigatingCommand}"
                        CommandParameter="{Binding}"/> <!-- what goes here -->
                </b:BehaviorCollection>
              </b:Interaction.Behaviors>
        </WebView>

但我不确定 CommandParameter 应该是什么 - 我需要被点击的 link 的 URI,但我不知道如何防止默认行为的发生。

这是最好的方法还是我应该寻找替代方法?

您无法使用 WebView 进行导航,必须使用自定义呈现 (hybridwebview)。 这是一个解释:

https://developer.xamarin.com/guides/xamarin-forms/application-fundamentals/custom-renderer/hybridwebview/

最近为了另一个项目重新访问了这个我偶然发现了 。更新后的 XAML 是:

<WebView
    x:Name="webView"
    HorizontalOptions="Fill" 
    VerticalOptions="FillAndExpand" 
    Source="{Binding WebViewSource}">
    <behaviors:Interaction.Behaviors>
        <behaviors:BehaviorCollection>
            <behaviors:EventToCommand
                EventName="Navigating"
                Command="{Binding NavigatingCommand}"
                PassEventArgument="True" />
        </behaviors:BehaviorCollection>
    </behaviors:Interaction.Behaviors>
</WebView>

ViewModel 中的代码是:

public Command<WebNavigatingEventArgs> NavigatingCommand
{
    get
    {
        return navigatingCommand ?? (navigatingCommand = new Command<WebNavigatingEventArgs>(
            (param) =>
            {
                if (param != null && -1 < Array.IndexOf(_uris, param.Url))
                {
                    Device.OpenUri(new Uri(param.Url));
                    param.Cancel = true;
                }
            },
            (param) => true
            ));
    }
}