sch*_*ebe 3 vb.net winforms webview2
今天,我决定将一个 VB.net 应用程序中的WebView控件迁移到另一个控件WebView2。
我已经安装WebView2并NuGet更改了声明和初始化行(我的 VB 程序中只有 4 行,因为我使用 2 个 WebView2)。
当我构建我的应用程序时,Visual Studio 2019表明该ScriptNotify事件不是WebView2!
Private Sub wvSelect_ScriptNotify(
sender As Object,
e As WebViewControlScriptNotifyEventArgs) Handles wvSelect.ScriptNotify
Run Code Online (Sandbox Code Playgroud)
使用旧WebView控件,该事件是使用windows.external.notifyJavascript 函数生成的。
function clickPlus(e) { window.external.notify("+PLUS:"); }
Run Code Online (Sandbox Code Playgroud)
哪个事件正在取代控制ScriptNotify中的事件WebView2?
我有兴趣了解新事件以及如何从 Javascript 调用该事件。
使用WebView2处理事件通知的一些可能场景:
另请参阅:在 WebView 中使用 JavaScript 进行扩展场景。
通用初始化:
myWebView2。Private Async Sub Load(sender As Object, e as EventArgs) Handles MyBase.Load
await myWebView2.EnsureCoreWebView2Async(Nothing)
End Sub
Run Code Online (Sandbox Code Playgroud)
另外,我正在使用这个简单的类模型,用于反序列化收到的 JSON 消息,因为WebView2.WebMessageReceived假定为 JSON 格式;不过,您可以传递任何您想要的字符串。
Private Class JsonEventMessage
Public Property Element As String
Public Property Value As String
End Class
Run Code Online (Sandbox Code Playgroud)
1 -在这种情况下,javascript 函数已在 HTML 中定义
JSON.stringify()强调返回值是一个JSON对象Private Async Sub Load(sender As Object, e as EventArgs) Handles MyBase.Load
await myWebView2.EnsureCoreWebView2Async(Nothing)
End Sub
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您只需要订阅事件WebMessageReceived并反序列化 JSON:
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
Console.WriteLine(message.Element)
Console.WriteLine(message.Value)
End Sub
Run Code Online (Sandbox Code Playgroud)
注意:我使用的是e.TryGetWebMessageAsString()而不是e.WebMessageAsJson,因为后者用引号引起来(双字符串化)。当您传递简单的字符串时最好使用它。
2 -此处定义了一个可以通知消息的 JavaScript 函数HEAD,但没有在其他任何地方添加事件处理程序。
假设您将在运行时添加 HTML 元素,或者您不想在 HTML 或其他任何内容中添加事件处理程序。
Private Class JsonEventMessage
Public Property Element As String
Public Property Value As String
End Class
Run Code Online (Sandbox Code Playgroud)
像以前一样订阅事件WebMessageReceived和NavigationCompleted事件。加载文档时会引发此事件。我们需要此事件,因为在示例中,事件处理程序被添加到主体中的元素中,而在此之前这是不可用的。
在 中NavigationCompleted,我们可以将 JavaScript Function 添加到字符串中并调用WebView2.ExecuteScriptAsync()方法,该方法在 DOM 准备好后执行脚本,否则GetElementById()将找不到目标。
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.NavigationCompleted, AddressOf myWebView2_NavigationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
Dim func As String =
"document.getElementById('div1').
addEventListener('click', function(e) {
SomeFunction(e, '+PLUS:')
});"
Await myWebView2.ExecuteScriptAsync(func)
End Sub
Run Code Online (Sandbox Code Playgroud)
3 -这次,HTML 中的任何位置都没有定义 JavaScript 函数。
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function SomeFunction(e, v) {
var json = JSON.stringify({ Element:e.target.id, Value:v });
window.chrome.webview.postMessage(json);
}
</script>
</head>
<body>
<script>
document.getElementById("div1").addEventListener("click", function(e) {SomeFunction(e, '+PLUS:')});
</script>
<div id="div1">Some Text to Click</div>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
案例1:
像以前一样
订阅WebMessageReceived和NavigationCompleted事件。
在 中NavigationCompleted,发布消息的 JavaScript 函数被直接添加到事件处理程序中。调用ExecuteScriptAsync()以执行脚本并将事件侦听器添加到 HTML 元素。
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.NavigationCompleted, AddressOf myWebView2_NavigationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_NavigationCompleted(sender As Object, e As CoreWebView2NavigationCompletedEventArgs)
Dim func As String =
"document.getElementById('div1').
addEventListener('click', function(e) {
var json = JSON.stringify({Element:e.target.id, Value:'+PLUS:'});
window.chrome.webview.postMessage(json);
});"
Await myWebView2.ExecuteScriptAsync(func)
End Sub
Run Code Online (Sandbox Code Playgroud)
情况2:
订阅WebMessageReceivedWebView2.CoreWebView2InitializationCompleted 。在本例中,我们向文档添加一个事件侦听器,然后使用该成员以及可用于处理通知的任何其他属性或值来
确定单击了哪个元素。Event.Target
在这里,我只是将[Event].target.id和[Event].target.innerText作为 JSON 属性传递。当然,您可以获取用例中所需的任何其他属性。
AddHandler myWebView2.WebMessageReceived, AddressOf myWebView2_WebMessageReceived
AddHandler myWebView2.CoreWebView2InitializationCompleted, AddressOf myWebView2_CoreWebView2InitializationCompleted
' [...]
Private Sub myWebView2_WebMessageReceived(sender As Object, e As CoreWebView2WebMessageReceivedEventArgs)
Dim message = New JavaScriptSerializer().
Deserialize(Of JsonEventMessage)(e.TryGetWebMessageAsString())
' [...]
End Sub
Private Async Sub myWebView2_CoreWebView2InitializationCompleted(
sender As Object,
e As CoreWebView2InitializationCompletedEventArgs)
Dim func as String =
"document.addEventListener
('click', function(e) {
window.chrome.webview.postMessage(
JSON.stringify({ Element:e.target.id, Value:e.target.innerText })
);
});"
Await myWebView2.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(func)
End Sub
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6947 次 |
| 最近记录: |