【发布时间】:2020-07-25 20:53:19
【问题描述】:
我想制作一个 xamarin 表单 webview 应用程序,该应用程序下载网页(应用程序本身)然后显示它。在下载之前,我会显示一个本地登录页面,一旦用户提交表单,它将调用该应用程序。本地页面将在应用程序包内,下载的页面将下载到应用程序可以存储数据的位置(此 uwp 示例中的 CommenApplicationData,但我必须使用 iOS 上的文档文件夹)。
我已经制作了一个 .NET Core 库,可以下载、解包并支持 webview 中的网页使用的脚本命令。该库的主要入口类称为:BroadsheetInterface,它接受来自 webview (BroadsheetInterface.RunCommand) 的消息,并使用接口对 webview(RunJavascript) 进行回调。
为了显示本地“登录页面”和下载的“应用程序页面”或“启动器页面”,我使用了 Xamarin 的 HybridWebView 示例。然后我修改了平台特定的 hybridwebview 来做它自己的导航,如下所示:
// IWebView is a interface that is used for the BroadsheetInterface can do callbacks
// to this control
public class HybridWebViewRenderer : ViewRenderer<HybridWebView, Windows.UI.Xaml.Controls.WebView>, IWebView
{
// The pointer to the current "BroadsheetInterface", a class that has all logic of
// the webpage inside the webview
public BroadsheetInterface_Helper BroadsheetInterface { get; set; }
// The standard call to setup the webview to a local page, I use this call to show
// the login page.
protected override void OnElementChanged(ElementChangedEventArgs<HybridWebView> e)
{
base.OnElementChanged(e);
if (Control == null)
{
SetNativeControl(new Windows.UI.Xaml.Controls.WebView());
}
if (e.OldElement != null)
{
Control.NavigationCompleted -= OnWebViewNavigationCompleted;
Control.ScriptNotify -= OnWebViewScriptNotify;
}
if (e.NewElement != null)
{
Control.NavigationCompleted += OnWebViewNavigationCompleted;
Control.ScriptNotify += OnWebViewScriptNotify;
LoadLoginPage();
}
}
// Once the local page has been loaded I setup the library (note the "this"
// parameter), then check if the user has checked the "remember login" checkbox
// last time he or she logged in.
void OnWebViewNavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
if (args.IsSuccess)
{
BroadsheetInterface = new BroadsheetInterface_Helper(this);
BroadsheetInterface.Browser_SetLogin();
}
}
// If the Javascript inside the webview calls the app, the command will be passed
// into the BroadsheetInterface to be processed.
void OnWebViewScriptNotify(object sender, NotifyEventArgs e)
{
BroadsheetInterface.RunCommand(e.Value);
}
// If the library want to call the webpage inside the webview, it will call
// this function
public async void RunJavascript(string script)
{
await Control.InvokeScriptAsync("eval", new[] { script });
}
// Show the login page
public void LoadLoginPage()
{
Control.Source = new Uri(string.Format("ms-appx-web:///Content//{0}", Element.Uri));
}
// Show the launcher page
public void LoadLauncherPage()
{
// The location of the launcher page
var fullname = BroadsheetInterface.AccountHelper.CurrentAccount.GetLauncherPage().FullName;
// fullname = "C:\Users\wille\AppData\Local\Packages\a05728a3-841f-4ef2-8f13-f1dbf39590a0_tbz3402trp7yy\LocalState\ProgramData\Launcher\willem\index.html"
// Convert the path to a url
var url = "file:///" + fullname.Replace("\\", "/");
// url = "file:///C:/Users/wille/AppData/Local/Packages/a05728a3-841f-4ef2-8f13-f1dbf39590a0_tbz3402trp7yy/LocalState/ProgramData/Launcher/willem/index.html"
// Set it to the webview
Control.Source = new Uri(url);
// DOESN'T WORK :(
}
// This is called from the library to get the location where to store
// the launcher page
public string GetCacheFolder()
{
return Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
}
}
现在应用程序运行,我可以登录,当我提交时,它开始下载文件。下载文件后,我想设置 webview 以显示已下载的启动器页面。所以我调用了“LoadLauncherPage()”函数,但它不会更改为下载的页面。这就像设置“Source”参数没有任何作用。
【问题讨论】:
标签: c# xamarin.forms uwp