我的 WPF 应用程序正在创建多个 WebBrowser 控件。我知道如何操作其中的 HtmlDocument 以及如何处理它们上的鼠标事件。但是,在具有 IHTMLEventObj2 对象作为参数的鼠标事件中,如何检索托管 WebBrowse?我可以通过 srcElement.document 访问该文档,但是如何“向上导航”到托管该文档的 WebBrowser?我想过使用“标签”属性,但 HTMLDocument 没有。作为最后的手段,我可能可以使用基于 HtmlDocument 对象的哈希表,但这对于这么简单的事情来说有点复杂......
1 回答
你在哪里/如何得到你的鼠标事件和srcElement.document
?它看起来像javascript。
如果为真,那么我很确定您无法从 JavaScript 访问 Web 控件,因为 Web 控件未在 DOM 树中公开。您可以尝试使用window.external
(或类似的)并通过它公开方法,然后让这些方法在网络浏览器上运行,但这有点令人费解,但我相信这种方式是可能的。
如果不是真的,并且如果您在 C# 中有一些 mouseevent 处理程序,那么只需在调用事件之前将处理程序与 webbrowser 链接。代替:
// inside your Window/etc:
private int otherData;
private void MyHandler(...args) {
if(otherData > 5)
browser.Navigate("foobar.html");
}
WebBrowser wb = ...;
wb.themouseevent += myhandler; // equivalent to wb.themouseevent += this.myhandler;
使用闭包或自定义对象从将“知道”浏览器的对象公开处理程序:
// inside or outside your Window/etc:
class MyHandlersWithSomeData
{
public WebBrowser browser;
public string someContextuaData;
public int otherData;
....
public void MyHandler(...args) {
if(otherData > 5)
browser.Navigate("foobar.html");
}
}
// inside your Window/etc:
WebBrowser wb = ...;
var smartHandler = new MyHandlersWithSomeData{ browser = wb, otherData = 10 };
wb.themouseevent += smartHandler.MyHandler; // note that handler is not from "this" anymore
编辑:正如你所问,“更简单”的方法是使用 lambdas 和闭包:
// inside your Window/etc:
private int otherData;
private void JustAMethodNotAHandler(WebBrowser browser, object sender, EventArgs args) {
if(otherData > 5)
browser.Navigate("foobar.html");
}
WebBrowser wb = ...;
wb.themouseevent += (sender, args) => JustAMethodNotAHandler(wb, sender, args);
然而,没有魔法。在引擎盖下,它几乎与上面的示例完全一样,带有一个额外的类,即所谓的“闭包”。此类将存储对WebBrowser wb
局部变量的引用,并且仅由于这一点,当JustAMethodNotAHandler
稍后调用时,该wb
方法仍然可用并且可以传递给该方法。
但是,由于我们现在使用 lambda((blah)=>blah
语法)来快速创建委托,因此您必须注意两件非常重要的事情:
JustAMethodNotAHandler
不是处理程序,它只是一种方法。由 lambda 创建的匿名函数将是实际的处理程序由于匿名函数是匿名的,如果您以后想取消注册它,您将很难。尝试如下:
wb.themouseevent -= (sender, args) => JustAMethodNotAHandler(wb, sender, args);
将不起作用,因为每次执行该行时,都会创建一个新的处理程序,完全不等于使用 += 创建的处理程序