高效读写数据
尽管Foxtable为WebViewer扩展了内置DOM,提升了混合编码的便利性,但在批量处理元素取值/赋值时,内置DOM写法仍存在大量冗余。
测试页面准备
假定我们的测试页面包含以下输入框(用于演示取值 / 赋值功能):
'''Async
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Await
wv.EnsureCoreWebView2Async(Nothing)
'初始化浏览器
'
定义测试页面(每个输入框新增初始值)
Dim
html
As
String
=
<![CDATA[
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>批量取值赋值测试</title>
<style>
*{font-size:15px; margin:5px;}
label{display:inline-block; width:70px; text-align:right;}
input{padding:6px 8px; width:200px; border:1px solid #ccc;
border-radius:4px;}
</style>
</head>
<body>
<h3>批量取值赋值测试</h3>
<div>
<label>产品:</label><input
type="text" id="product" value="PD001"/><br>
<label>客户:</label><input
type="text" id="customer" value="CS001"/><br>
<label>雇员:</label><input
type="text" id="employee" value="EP001"/><br>
<label>单价:</label><input
type="number" id="price" step="0.01" min="0" value="59.99"/><br>
<label>折扣:</label><input
type="number" id="discount" step="0.01" min="0" max="1" value="0.1"/><br>
<label>数量:</label><input
type="number" id="qty" step="1" min="1" value="100"/><br>
<label>日期:</label><input
type="date" id="date" value="2026-01-01"/><br>
</div>
</body>
</html>
]]>.Value
wv.NavigateToString(html)
内置DOM的痛点
若使用内置DOM读取上述输入框的值,代码会极其繁琐:
'''Async
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
' 1.
产品(字符串类型)
Dim
productEle = wv.getElementById("product")
Dim
productRlt
As
String
=
Await
productEle.value
Dim
product
As
String
= productRlt.Trim("""")
' 2.
客户(字符串类型)
Dim
customerEle = wv.getElementById("customer")
Dim
customerRlt
As
String
=
Await
customerEle.value
Dim
customer
As
String
= customerRlt.Trim("""")
' 3.
雇员(字符串类型)
Dim
employeeEle = wv.getElementById("employee")
Dim
employeeRlt
As
String
=
Await
employeeEle.value
Dim
employee
As
String
= employeeRlt.Trim("""")
' 4.
单价(数值类型)
Dim
priceEle = wv.getElementById("price")
Dim
priceRlt
As
String
=
Await
priceEle.value
Dim
priceStr
As
String
= priceRlt.Trim("""")
Dim
price
As
Double
=
If(priceStr
=
"",
0.0,
CDbl(priceStr))
' 5.
折扣(数值类型)
Dim
discountEle = wv.getElementById("discount")
Dim
discountRlt
As
String
=
Await
discountEle.value
Dim
discountStr
As
String
= discountRlt.Trim("""")
Dim
discount
As
Double
=
If(discountStr
=
"",
0.0,
CDbl(discountStr))
' 6.
数量(整数类型)
Dim
qtyEle = wv.getElementById("qty")
Dim
qtyRlt
As
String
=
Await
qtyEle.value
Dim
qtyStr
As
String
= qtyRlt.Trim("""")
Dim
qty
As
Integer
=
If(qtyStr
=
"",
1,
CInt(qtyStr))
' 7.
日期(日期类型)
Dim
dateEle = wv.getElementById("date")
Dim
dateRlt
As
String
=
Await
dateEle.value
Dim
dateStr
As
String
= dateRlt.Trim("""")
Dim
dtm
As
Date
=
If(dateStr
=
"",
Date.MinValue,
CDate(dateStr))
原因是:无论输入框类型如何,内置DOM返回的都是带双引号的字符串,我们不仅要手动去掉双引号,还要进行数据类型转换,才能获得最终的结果。
WebViewer扩展方法(高效方案)
为了让大家更方便地赋值和取值,Foxtable给WebViewer另外扩展了几个方法:
GetValuesByID
用于一次性获取多个元素的值(存储在ExpandoObject对象中)。
GetValuesByID会自动处理双引号和类型转换,不需要额外编码,参数为元素ID的数组或集合。
例如要获取上述页面所有输入框的值,代码如下:
'''Async
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
ids
As
String()
= {"product",
"customer",
"employee",
"price",
"discount",
"qty",
"date"}
Dim
result
As
Object
=
Await
wv.GetValuesByID(ids)
Dim
product
As
String
= result.product
Dim
customer
As
String
= result.customer
Dim
employee
As
String
= result.employee
Dim
price
As
Double
= result.price
Dim
discount
As
Double
= result.discount
Dim
qty
As
Integer
= result.qty
Dim
dtm
As
Date
= result.date
由于GetValuesByID自动完成了类型转换,可以直接使用返回的值:
'''Async
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
ids
As
String()
= {"product",
"customer",
"employee",
"price",
"discount",
"qty",
"date"}
Dim
result
As
Object
=
Await
wv.GetValuesByID(ids)
Dim
Year
As
Integer
= result.date.Year
'返回的值已经进行了正确的类型转化,可以直接用
MessageBoxA.Show(Year)
如果元素没有输入值,则返回Nothing,所以使用GetValuesByID取值时做空值判断
是非常方便的:
'''Async
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
ids
As
String()
= {"product",
"customer",
"employee",
"price",
"discount",
"qty",
"date"}
Dim
result
As
Object
=
Await
wv.GetValuesByID(ids)
If
result.date
Is
Nothing
Then
MessageBoxA.Show("请输入日期")
Else
Dim
Year
As
Integer
= result.date.year
End
If
GetValueByID
用于获取单个元素的值,会自动去双引号和类型转换,不需要额外编码,功能和GetValuesByID完全一样。
例如取产品和数量两个元素的值:
Dim
product
As
String
=
Await
wv.GetValueByID("product")
Dim
qty
As
Integer
=
Await
wv.GetValueByID("qty")
提示:可以用多个GetValueByID代替GetValuesByID,前者编码方便,后者效率更高(一次性取回所有值),当然这种效率差距我们很难感受得到。
SetValuesByID
用于一次性设置多个元素的值,有两个参数,参数1为元素ID的数组/集合,参数2为对应值的数组/集合。
例如一次性设置上述输入框的值:
Dim
wv
As
WebViewer = e.Form.Controls("WebViewer1").WebViewer
Dim
ids
As
String()
= {"product",
"customer",
"employee",
"price",
"discount",
"qty",
"date"}
Dim
vals
As
Object()
= {"PD99",
"CS88",
"EP77",
99.99,
0.15,
888,
"2026-12-31"}
wv.SetValuesByID(ids, vals)
SetValueByID
用于设置单个元素的值,有两个参数,分别用于指定元素ID和值。
例如设置数量值:
wv.SetValueByID("qty",
200)
提示:可以用多个SetValueByID代替SetValuesByID,前者编码方便,后者效率更高(一次性设置所有值),当然这种效率差距我们很难感受得到。