1

我正在开发一个 Windows 窗体 UserControl,以使用 webBrowser 控件呈现一些 HTML 并与之交互。部分内容是一些单选按钮,我需要从我的控件中捕获点击事件。因此,在 webBrowser 的 DocumentCompleted 事件中,我将 onClick 事件附加到单选按钮。在我单击其中一个单选按钮之前,所有这些似乎都有效,似乎只有最后一个单选按钮实际上附加了事件,即使我已经单步执行了代码并且每个单选按钮都附加了委托。

这是我用来将委托附加到 HtmlElement 的 lambda。

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);
 }

AnswerSelected 的委托和事件

public delegate void HtmlControlAnswerEventHandler(Guid answerId);
public event HtmlControlAnswerEventHandler AnswerSelected;

输入按钮字符串。

<input type=radio id="{0}" name="answer" value="{1}" />
4

2 回答 2

1

似乎当使用像这样的 lambdas 时,用于引用对象的变量丢失了。如果我以这种方式附加事件

void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
     foreach (HtmlElement el in webBrowser1.Document.GetElementsByTagName("input"))
     {
         el.AttachEventHandler("onclick", (sender1, e1) => clickEventHandler(el, EventArgs.Empty));
     }
}

那么只有最后一个附加的事件是有效的。

当我以这种方式附加事件时

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));
      }
 }

inder i 变得大于元素数量存在问题(这让我很难过。)

但是,如果我以这种方式附加事件

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));
     }
}

然后一切都按预期工作。我不完全确定为什么会这样,否则在附加委托时我们可能需要对对象的硬引用?

于 2012-07-25T16:24:04.290 回答
1

el变量范围的问题。在评估委托时,循环已完成并el保存最后一个列表项的值。您可以通过分配el给循环内的变量来解决此问题。

void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
     foreach (HtmlElement _el in webBrowser1.Document.GetElementsByTagName("input"))
     {
         HtmlElement el = _el;
         el.AttachEventHandler("onclick", (sender1, e1) => clickEventHandler(el, EventArgs.Empty));
     }
}
于 2018-03-14T18:45:27.777 回答