I am working on a windows form UserControl to render and interact with some HTML using the webBrowser control. Part of the content are some radio buttons that I need to capture click events from within my control. So in the DocumentCompleted event of the webBrowser I am attaching an onClick event to the radio buttons. All of this seems to work until I click on one of the radio buttons, it seems that only the final radio button is actually having the event attached, even though I have stepped through the code and the delegate is being attached for each radio button.
This is the lambda I am using to attach the delegate to the HtmlElement.
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
foreach (HtmlElement el in webBrowser1.Document.GetElementsByTagName("input"))
{
el.AttachEventHandler("onclick", (sender1, e1) => clickEventHandler(el, EventArgs.Empty));
}
}
public void clickEventHandler(object sender, EventArgs e)
{
Guid answerId;
var he = (HtmlElement)sender;
if (Guid.TryParse(he.Id, out answerId))
if (AnswerSelected != null)
AnswerSelected(answerId);
}
Delegate and event for AnswerSelected
public delegate void HtmlControlAnswerEventHandler(Guid answerId);
public event HtmlControlAnswerEventHandler AnswerSelected;
Input button string.
<input type=radio id="{0}" name="answer" value="{1}" />
It seems that when using lambdas like this the variable used to reference the object is lost. If I attach the events this way
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
foreach (HtmlElement el in webBrowser1.Document.GetElementsByTagName("input"))
{
el.AttachEventHandler("onclick", (sender1, e1) => clickEventHandler(el, EventArgs.Empty));
}
}
then only the last attached event is valid.
When I attach the events this way
private void AttachClickEventToInputs()
{
var htmlElements = webBrowser1.Document.GetElementsByTagName("input");
for (int i = 0; i < htmlElements.Count; i++)
{
htmlElements[i].AttachEventHandler("onclick", (sender1, e1) => clickEventHandler(htmlElements[i], EventArgs.Empty));
}
}
There is an issue with the inder i becoming greater then the number of elements (this stumps me.)
However if I attach the events this way
private void AttachClickEventToInputs()
{
var htmlElements = webBrowser1.Document.GetElementsByTagName("input");
for (int i = 0; i < htmlElements.Count; i++)
{
HtmlElement el = htmlElements[i];
el.AttachEventHandler("onclick", (sender1, e1) => clickEventHandler(el, EventArgs.Empty));
}
}
then everything works as intended. I am not completly sure why this works, other then maybe we need a hard reference to the object when attaching delegates?