Data Binding Guide - BindUI / BindData / SetData
📖 Table of Contents
- Overview
- Architecture Principles
- BindUI - Event Binding
- BindData - Data Binding
- SetData - Data Pushing
- Auto-Rebuild After Navigation
- Complete Example
- FAQ
Overview
The data binding system in cWebView2Host is a declarative VB6-Web two-way communication mechanism that eliminates the need for manually writing JSON message parsing, DOM manipulation, or event listener glue code.
✨ Core Features
- 🔗 Two-Way Binding - BindUI (UI→Host) + BindData (Host→UI) covers bidirectional communication
- 📝 Declarative - One binding declaration replaces extensive glue code
- 🔄 Auto-Rebuild - Binding logic is automatically re-injected after page navigation
- 🎯 CSS Selectors - Standard CSS selectors for locating DOM elements
- 📦 Batch Operations - SetDataBatch pushes multiple data values at once
Architecture Principles
System Composition
cWebView2Host.BindUI() / BindData() / SetData()
│
▼
WebView2BindUIProxy (COM object, exposed as JS global object bindUIProxy)
│
├── BindUI: JS addEventListener → bindUIProxy.onEvent(bindId, eventName, detail)
│ └── CallByName(HostInst, MethodName, vbMethod, EventName, Detail)
│
├── BindData: SetData → JS loop through binding list → element[attr] = value
│
└── Navigation rebuild: DOMContentLoaded → inject rebind JS → restore all BindUI + BindData + DataValueWorkflow
1. VB6 calls BindUI/BindData → Register bindings in WebView2BindUIProxy internal collection
2. GetJsCode() → Load ProxyBindUI.js / ProxyMouseEvents.js from embedded resources
3. GetBindAddJs() → Generate addEventListener JS code
4. ExecuteScript() → Inject and execute binding code in WebView2
5. DOM event fires → JS calls bindUIProxy.onEvent() → CallByName → VB6 method callback
6. SetData call → Generate JS code → Iterate binding list → Update DOM attributesBindUI - Event Binding
Basic Usage
' Bind #submit-btn click event to Me.OnButtonClick
wv.BindUI Me, "OnButtonClick", "#submit-btn"After declaration, when the user clicks the #submit-btn element in WebView2, VB6 automatically calls the OnButtonClick method.
Host Method Signature
All BindUI callback methods must follow this signature:
Public Sub OnButtonClick(ByVal EventName As String, ByVal Detail As String)
' EventName: The DOM event name that fired (e.g., "click", "input", "change")
' Detail: JSON-formatted event details
End SubDetail Parameter Parsing
Detail is a JSON string whose content depends on the DOM event type. Common event Detail structures:
| Event | Detail Example |
|---|---|
| click | {"type":"click","target":"#btn"} |
| input | {"type":"input","value":"User input text"} |
| change | {"type":"change","value":"new value","checked":true} |
Since VB6 has no built-in JSON parser, simple string processing is typically used:
Public Sub OnNameInput(ByVal EventName As String, ByVal Detail As String)
' Simple value field extraction
Dim val As String
val = JsonValue(Detail, "value")
wv.SetData "name", val
End Sub
' Simple JSON value extraction helper function
Private Function JsonValue(ByVal Json As String, ByVal Key As String) As String
Dim pos As Long
pos = InStr(Json, """" & Key & """:""")
If pos > 0 Then
pos = pos + Len(Key) + 3
Dim endPos As Long
endPos = InStr(pos, Json, """")
If endPos > 0 Then
JsonValue = Mid(Json, pos, endPos - pos)
End If
End If
End FunctionCustom Event Names
Click event is bound by default; specify other events via the EventName parameter:
' Bind input event (real-time text input response)
wv.BindUI Me, "OnNameInput", "#name-input", EventName:="input"
' Bind change event (select/checkbox value change)
wv.BindUI Me, "OnToggle", "#toggle-enabled", EventName:="change"
' Bind submit event
wv.BindUI Me, "OnFormSubmit", "#my-form", EventName:="submit"Multi-Element Binding
' Multiple buttons bound to different methods
wv.BindUI Me, "OnSave", "#btn-save"
wv.BindUI Me, "OnCancel", "#btn-cancel"
wv.BindUI Me, "OnReset", "#btn-reset"
' Same element, different events bound to different methods
wv.BindUI Me, "OnFocus", "#input", EventName:="focus"
wv.BindUI Me, "OnBlur", "#input", EventName:="blur"Removing Bindings
' Remove all event bindings for specified element
wv.UnbindUI "#submit-btn"
' Remove only a specific event binding for the element
wv.UnbindUI "#name-input", "input"BindData - Data Binding
Principles
BindData binds a data key name to a DOM element's specific attribute. When SetData updates the key name, all DOM element attributes bound to that key are automatically updated.
Supported DOM Attributes
| Attribute | Description | Example |
|---|---|---|
textContent | Element text content (default) | Labels, paragraphs |
value | Form element value | input, textarea, select |
innerHTML | Element inner HTML | Dynamic HTML rendering |
src | Resource source | img, video, iframe |
class | CSS class name | State style switching |
checked | Checked state | checkbox, radio |
visible | Show/hide (custom) | Any element |
| Other attributes | Directly set DOM attribute | href, disabled, style, etc. |
Basic Usage
' Bind data key to element attribute
wv.BindData "name", "#name-input", "value"
wv.BindData "message", "#msg-display", "textContent"
' Same key bound to multiple elements/attributes
wv.BindData "name", "#name-input", "value"
wv.BindData "name", "#name-preview", "textContent" ' Same data, different attribute
' Bind to special attributes
wv.BindData "enabled", "#toggle", "checked" ' checkbox
wv.BindData "enabled", "#panel", "visible" ' show/hide
wv.BindData "avatar", "#avatar-img", "src" ' image URL
wv.BindData "status", "#status-dot", "class" ' CSS class name
wv.BindData "items", "#list", "innerHTML" ' HTML fragmentvisible Attribute
visible is a virtual attribute custom to cWebView2Host that controls DOM element visibility:
wv.BindData "showPanel", "#settings-panel", "visible"
' When showPanel = True, JS sets element.style.display = ''
' When showPanel = False, JS sets element.style.display = 'none'class Attribute
The class attribute replaces the element's entire CSS class name:
wv.BindData "statusOnline", "#status-dot", "class"
wv.SetData "statusOnline", "dot online" ' Green online status
wv.SetData "statusOnline", "dot offline" ' Gray offline statusSetData - Data Pushing
SetData
Push a single data value. Supports String, Boolean, and Number types:
wv.SetData "name", "Zhang Wei" ' String
wv.SetData "enabled", True ' Boolean
wv.SetData "count", 42 ' Number
wv.SetData "avatar", "https://example.com/a.png" ' URL stringType Conversion Rules:
- VB6
String→ JS string (auto-quoted) - VB6
Boolean→ JS boolean (true/false) - VB6 numeric types → JS number (passed directly)
SetDataBatch
Batch push multiple data values; parameter is a JSON object string:
wv.SetDataBatch "{""name"":""Zhang Wei"",""enabled"":true,""count"":42}"Suitable for pushing all data at once during page initialization.
Auto-Rebuild After Navigation
When WebView2 navigates to a new page, previously injected JavaScript binding code is destroyed. cWebView2Host handles this automatically:
Rebuild Mechanism
- After each navigation triggers DOMContentLoaded, rebuild is automatically triggered
GetReattachJs()generates JS code to rebuild all bindings- Rebuild includes: BindUI event listeners + BindData declarations + DataValue current values
DataValue Persistence
Values pushed by SetData are automatically stored in the m_DataValues collection. After page navigation, these values are automatically re-applied to the DOM:
' First navigation
wv.SetData "name", "Zhang Wei"
' User clicks a link to navigate to a new page
' → DOMContentLoaded triggers auto-rebuild
' → "name" key's value "Zhang Wei" is automatically re-appliedComplete Example
The following example demonstrates the complete cooperation of BindUI/BindData/SetData:
VB6 Code
Dim WithEvents wv As cWebView2Host
Private Sub Form_Load()
Set wv = New cWebView2Host
wv.Initialize Me.hWnd, App.Path & "\www"
End Sub
Private Sub wv_Ready()
' === Host -> UI Data Binding ===
wv.BindData "name", "#name-input", "value"
wv.BindData "name", "#name-preview", "textContent"
wv.BindData "enabled", "#toggle-enabled", "checked"
wv.BindData "enabled", "#settings-panel", "visible"
wv.BindData "avatar", "#avatar", "src"
wv.BindData "count", "#msg-count", "textContent"
wv.BindData "statusOnline", "#status-dot", "class"
' === UI -> Host Event Binding ===
wv.BindUI Me, "OnNameInput", "#name-input", EventName:="input"
wv.BindUI Me, "OnToggle", "#toggle-enabled", EventName:="change"
wv.BindUI Me, "OnIncMsg", "#btn-inc"
wv.BindUI Me, "OnResetMsg", "#btn-reset"
' === Push Initial Data ===
wv.SetData "name", "Zhang Wei"
wv.SetData "enabled", True
wv.SetData "count", 0
Me.Caption = wv.DocumentTitle
End Sub
' === UI Callback Methods ===
Public Sub OnNameInput(ByVal EventName As String, ByVal Detail As String)
Dim val As String
val = JsonValue(Detail, "value")
wv.SetData "name", val ' Push back to UI
End Sub
Public Sub OnToggle(ByVal EventName As String, ByVal Detail As String)
' Detail example: {"type":"change","checked":true}
Dim checked As Boolean
checked = (InStr(Detail, """checked"":true") > 0)
wv.SetData "enabled", checked
End Sub
Public Sub OnIncMsg(ByVal EventName As String, ByVal Detail As String)
Dim count As Long
count = Val(wv.JsProp("document.querySelector('#msg-count').textContent"))
wv.SetData "count", count + 1
End Sub
Public Sub OnResetMsg(ByVal EventName As String, ByVal Detail As String)
wv.SetData "count", 0
End SubHTML Page
<div>
<input id="name-input" type="text" />
<p>Hello, <span id="name-preview">-</span>!</p>
</div>
<div>
<label><input id="toggle-enabled" type="checkbox" /> Enable</label>
<div id="settings-panel">
<p>Settings content here</p>
</div>
</div>
<div>
<span id="msg-count">0</span> messages
<button id="btn-inc">+</button>
<button id="btn-reset">Reset</button>
</div>FAQ
❓ Q1: BindUI callback not being triggered?
Symptom: Event is bound but VB6 method is not called.
Reason:
- Host method must be declared as
Public(not Private) - Host method signature must exactly match
(ByVal EventName As String, ByVal Detail As String) - Binding must be executed in
wv_Readyevent or later, not inForm_Load
Solution:
' Correct
Public Sub OnClick(ByVal EventName As String, ByVal Detail As String)
' Incorrect
Private Sub OnClick(ByVal EventName As String, ByVal Detail As String) ' Cannot be Private
Public Sub OnClick() ' Parameter signature mismatch❓ Q2: Original styles lost when using BindData with class attribute?
Symptom: After using BindData "key", "#element", "class", the element's original CSS classes are overwritten.
Reason: The class attribute directly replaces the element's entire className, it does not append.
Solution: Compose the full class name before calling SetData:
wv.SetData "statusClass", "card " & IIf(isActive, "active", "inactive")❓ Q3: Bindings stop working after page navigation?
Symptom: After clicking a link and navigating to a new page, bindings no longer work.
Reason: cWebView2Host automatically rebuilds bindings on DOMContentLoaded, but if the new page has a different DOM structure (selectors don't match elements), bindings silently fail.
Solution:
- Ensure all pages have consistent DOM IDs/selectors
- Or re-execute bindings after navigation
❓ Q4: How to pass complex objects with SetData?
Symptom: Need to pass arrays or objects to JS.
Reason: SetData's Value is Variant, internally converted to JS literal. Complex types need to be serialized to JSON string and use innerHTML or custom JS processing.
Solution:
' Method 1: Use innerHTML to render a list
wv.BindData "items", "#item-list", "innerHTML"
wv.SetData "items", "<li>Item 1</li><li>Item 2</li>"
' Method 2: Directly call JS function to process JSON
wv.JsRun "renderItems(" & jsonString & ")"Last Updated: 2026-06-24