WebBrowser 元素事件和值





5.00/5 (11投票s)
程序化地获取/设置 WebBrowser 按钮元素事件和输入元素值,无需 Web 服务器。

引言
我正在为 Intertexti 添加一个功能,在该功能中,我可以创建 HTML 表单并记录用户特定于笔记卡的数据。 此外,我希望能够这样做,而无需后端的服务器。 想法是能够获取/设置文本输入字段的值,并捕获单选按钮、复选框和普通按钮的鼠标点击事件。 我对如何做到这一点的搜索带我去了几个地方
演示程序使用 .NET 的 WebBrowser
控件(如果你阅读了 Intertexti 文章,是的,我放弃了 webkit.net,即使我随后让 open-webkit-sharp 编译并工作,它也有很多问题,不值得继续研究。)
测试表单
我在测试程序中硬编码了 HTML 以呈现上述网页
browser.DocumentText="<form>\r\n" + "First name: <input id='firstname' type='text' name='firstname'/><br/>\r\n" + "Last name: <input id='lastname' type='text' name='lastname'/><br/>\r\n" + "Password: <input id='password' type='password' name='pwd'/><br><br/>\r\n" + "<input type='radio' id='male' name='sex' value='male'/>Male<br/>\r\n" + "<input type='radio' id='female' name='sex' value='female'/>Female<br/><br/>\r\n" + "<input type='checkbox' id='bike' name='vehicle' value='Bike'/>I have a bike<br/>\r\n" + "<input type='checkbox' id='car' name='vehicle' value='Car'/>I have a car <br/><br/>\r\n" + "<input type='button' id='ok' value='OK'/><br/>\r\n" + "<input type='button' id='cancel' value='Cancel'/><br/><br/>\r\n" + "</from>";
DocumentCompleted 事件
事件处理程序必须在文档加载后才能连接,因此我们需要首先处理 DocumentCompleted
事件
public class Form1() { public Form1() { ... browser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(OnDocumentCompleted); } protected void OnDocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { WireUpButtonEvents(); } }
连接事件处理程序
对于实际的元素连接,我们使用元素方法 AttachEventHandler
。 不幸的是,当实际调用事件时,sender 参数为 null,因此我们改为利用匿名方法将事件转发给我们的实际处理程序,并将元素实例作为 sender 提供。 但是,这意味着我们需要匿名方法中的元素实际实例,因此使用索引循环而不是更典型的 foreach
迭代器。
最后,类型为单选按钮、复选框和按钮的元素通过连接 DOM "onclick
" 属性传递给 OnElementClicked
处理程序,而文本元素通过连接 DOM "onblur
" 属性传递给 OnElementLostFocus
处理程序。
protected void WireUpButtonEvents() { HtmlElementCollection elements = browser.Document.GetElementsByTagName("input"); // We have to use this form because of the lambda expression that is used to pass // in the element instance to the handler. This is the only way to actually get // the element instance, as the instance is not passed in if we just provide the // event sink method name. for (int i=0; i<elements.Count; i++) { HtmlElement el = elements[i]; string elType = el.GetAttribute("type"); switch (elType) { case "radio": case "checkbox": case "button": { // We need the element instance to know what was clicked. el.AttachEventHandler("onclick", (sender, args) => OnElementClicked(el, EventArgs.Empty)); break; } case "text": { // We need the element instance to know what was clicked. el.AttachEventHandler("onblur", (sender, args) => OnElementLostFocus(el, EventArgs.Empty)); break; } } } }
事件处理程序
最后,事件处理程序仅在浏览器控件下面的 textbox
中报告事件的发生
protected void OnElementClicked(object sender, EventArgs args) { HtmlElement el = sender as HtmlElement; string elType = el.GetAttribute("type"); string elName = el.GetAttribute("name"); string elValue = el.GetAttribute("value"); tbMessages.Text += "Clicked: " + elType + " " + elName + " " + elValue + "\r\n"; } protected void OnElementLostFocus(object sender, EventArgs args) { HtmlElement el = sender as HtmlElement; string elType = el.GetAttribute("type"); string elName = el.GetAttribute("name"); string elValue = el.GetAttribute("value"); tbMessages.Text += elType + " " + elName + " " + elValue + "\r\n"; }
恢复状态
如果你点击表单上的“设置数据”按钮,则会设置各种输入元素的状态
protected void SetFormState() { browser.Document.GetElementById("firstname").SetAttribute("value", "Marcia"); browser.Document.GetElementById("lastname").SetAttribute("value", "JohnDoe"); browser.Document.GetElementById("female").SetAttribute("checked", "1"); browser.Document.GetElementById("bike").SetAttribute("checked", ""); browser.Document.GetElementById("car").SetAttribute("checked", "1"); }
请注意,要取消选中复选框,需要将一个空字符串作为属性值传递。 另请注意,不需要“取消选中”单选按钮 - 浏览器会处理由 name 属性分组的所有单选按钮的此状态更改。
结论
希望此代码已简洁地说明了如何挂钩到 web 浏览器的事件,以通过编程方式响应按钮点击和文本值更改,以及如何将 web 浏览器的可编辑控件恢复到特定状态。