自定义对话框

本节内容可以参考示例文件"CaseStudy\WebViewer\自定义对话框.Table"。

WebViewer提供了ScriptDialogOpening事件,让我们可以接管网页中的JS对话框(alert、confirm、prompt),用Foxtable自己的对话框取而代之。

由WebViewer允许前端JS直接调用Foxtable的全部功能,所以本节存在的意义仅在于:不修改原有的网页代码就能用Foxtable对话框代替JS对话框

我们可以:

1、用 Foxtable 的 MessageBoxA 替代JS的 alert 和 confirm

2、用 Foxtable 的 InputValue 函数替代网页的 prompt,甚至直接设计一个复杂的窗口来代替之。

要启用自定义对话框,首先关闭默认对话框,代码为:

wv.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled =
False


然后设置ScriptDialogOpening事件代码显示自己的对话框或窗口。

该事件的e参数属性有:

属性 类型 说明
Kind CoreWebView2ScriptDialogKind 对话框类型:Alert、Confirm、Prompt、BeforeUnload
Message String 对话框显示的消息内容
Uri String 触发对话框的页面URL
DefaultText String 仅对Prompt有效,表示输入框的默认值
ResultText String 仅对Prompt有效,设置用户输入的返回值

该事件还有两个方法:

方法 说明
Accept() 接受对话框。对于不同对话框类型含义不同:

Alert:关闭对话框

Confirm:返回True(用户点击“是”)

Prompt:返回ResultText中设置的值

BeforeUnload:允许离开页面
GetDeferral() 获取延迟对象,用于异步处理对话框。必须在异步操作完成后调用Complete()。

示例

1、窗口的AfterLoad事件代码:

'''Async
Dim
wv As WebViewer = e.Form.Controls("WebViewer1").WebViewer
Await
wv.EnsureCoreWebView2Async(Nothing)
wv.CoreWebView2.Settings.AreDefaultScriptDialogsEnabled =
False 

' 构建测试页面
Dim
html As String = <![CDATA[
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>ScriptDialog
测试</title>
    <style>
        body { font-family:
微软雅黑; padding: 20px; background: #f5f7fa; }
        .container { max-width: 600px; margin: 0 auto; background: white; border-radius: 10px; padding: 20px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
        h2 { color: #333; border-bottom: 2px solid #0078d7; padding-bottom: 10px; }
        .btn-group { margin: 20px 0; }
        button { padding: 10px 20px; margin: 5px; border: none; border-radius: 5px; cursor: pointer; font-size: 14px; }
        .alert { background: #ffc107; color: #333; }
        .confirm { background: #17a2b8; color: white; }
        .prompt { background: #28a745; color: white; }
        .result { margin-top: 20px; padding: 15px; background: #f8f9fa; border-radius: 5px; border-left: 4px solid #0078d7; }
    </style>
</head>
<body>
    <div class="container">
        <h2>📋 ScriptDialog
测试</h2>
        <div class="btn-group">
            <button class="alert" onclick="showAlert()">Alert</button>
            <button class="confirm" onclick="showConfirm()">Confirm</button>
            <button class="prompt" onclick="showPrompt()">Prompt</button>
        </div>    
        <div class="result" id="result">
           
等待操作结果...
        </div>
        <script>
            function showAlert() {
                alert('
这是一个 Alert 对话框!');
                document.getElementById('result').innerText = 'Alert
已关闭';
            }           

            function showConfirm() {
                const result = confirm('
确定要继续操作吗?');
                document.getElementById('result').innerText = 'Confirm
结果: ' + (result ? '确定' : '取消');
            }           

            function showPrompt() {
                const result = prompt('
请输入您的名字:', '张三');
                if (result !== null) {
                    document.getElementById('result').innerText = 'Prompt
结果: ' + result;
                } else {
                    document.getElementById('result').innerText = 'Prompt
已取消';
                }
            }
        </script>
    </div>
</body>
</html>
]]>
.Value
wv.NavigateToString(html)

2、WebViewer的ScriptDialogOpening事件代码:

'''Async
Dim
diff = e.GetDeferral() '通知系统,Foxtable接管了,中间不要Return
Select
Case e.Kind
   
Case CoreWebView2ScriptDialogKind.Alert
       
Await MessageBoxA.Show(e.Message, "Foxable", MessageBoxButtons.OK, MessageBoxIcon.Information)
        e.Accept()
   
Case CoreWebView2ScriptDialogKind.Confirm
       
Dim result As DialogResult = Await MessageBoxA.Show(e.Message, "Foxtable", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
       
If result = DialogResult.Yes Then
            e.Accept()
' 调用 Accept() 表示用户点击,页面收到 true
       
Else
           
' 不调用 Accept() 表示用户点击
       
End If
   
Case CoreWebView2ScriptDialogKind.Prompt
       
Dim value As String = e.DefaultText
       
Dim isOK As Boolean
       
'由于涉及到UI,必须包装在同步代码中
        BaseMainForm.Invoke(
Sub()
            isOK = InputValue(value,
"网页 Prompt", e.Message)
       
End Sub)
       
If isOK Then
            e.ResultText = value
            e.Accept()
' 调用 Accept(),表示用户点击确定,返回输入值
       
Else
           
' 不调用 Accept() 表示用户点击取消
       
End If
End
Select
diff.Complete()
'通知系统,Foxtable处理结束

注意:

1. 首尾要调用 GetDeferral() 和 Complete(),由于事件处理中包含异步操作,必须先获取延迟对象并在最后调用Complete方法,否则页面可能会卡死。

2、MessageBoxA专门为异步操作设计,可以直接使用,但InputValue不是的, 由于其涉及UI(自己设计输入窗口也是),必须用BaseMainForm.Invoke包装执行,参考:插入同步代码


本页地址:http://www.foxtable.com/webhelp/topics/6270.htm