问题
In C#, I am running the WebBrowser (WB) control in a server-side thread and want to monitor (listen) for "onpropertychange" events. I can successfully attach a .NET delegate signature method that is executed when a property changes, but the sender and e objects are both null in every call to qEventHndlr, therefore, I don't know which property changed to fire the event. el is an HTMLElement that is iterated in a foreach loop to attach the eventhandler to each element to monitor (listen).
el.AttachEventHandler("onpropertychange", qEventHndlr); // in the foreach loop
public void qEventHndlr(Object sender, EventArgs e) {…} // the event handler
The documentation indicates that the EventArgs class; "This class contains no event data; it is used by events that do not pass state information to an event handler when an event is raised. If the event handler requires state information, the application must derive a class from this class to hold the data." It also seems (I'm not certain and haven't tested) that sender is only populated for a subset of WB events and not onpropertychange.
So, I then thought that if I can't get identifier information in the send or e objects, I could use an anonymous method in the AttachEventHandler and then pass a unique runtime programmable string parameter to a method embedded in the event handler method call.
el.AttachEventHandler("onpropertychange", delegate(Object sender, EventArgs e) { anonoMeth(elID); });
public void anonoMeth(string specificProperty) {..}
The compiler accepted the syntax, however, even though the elID string changes in the foreach loop, only the first iteration value is used so that when anonoMeth(string specificProperty) is called with each onpropertychange event, specificProperty has the same value because the same elID was attached to the respective element.
I haven't tried Extension Methods yet and wanted to get this posted to see if anyone has encountered similar challenges (and hopefully has a solution). I prefer not to resort to C++ unless I absolutely have to.
回答1:
You need to cast your sender
to an object of the appropriate type (an HTMLElement
in your case) in your event handler.
Try this example on for size:
namespace WebBrowserEventTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
webBrowserTest.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowserTest_DocumentCompleted);
webBrowserTest.Navigate("http://mondotees.com");
}
private void webBrowserTest_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
foreach(HtmlElement el in webBrowserTest.Document.GetElementsByTagName("div"))
{
el.AttachEventHandler("onpropertychange", delegate { testEventHandler(el, EventArgs.Empty); });
}
foreach (HtmlElement el in webBrowserTest.Document.GetElementsByTagName("div"))
{
el.Name = "test";
}
}
public void testEventHandler(object sender, EventArgs e)
{
var he = (HtmlElement)sender;
}
}
}
来源:https://stackoverflow.com/questions/9184856/event-handler-for-webbrowser-control-onpropertychange-events-sender-and-e-obje