【问题标题】:Attaching delegates to webBrowser html elements将委托附加到 webBrowser html 元素
【发布时间】:2012-07-25 14:31:55
【问题描述】:

我正在开发一个 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}" />

【问题讨论】:

  • 当你说testEventHandler时,你真的是指clickEventHandler吗?
  • 酷,AnswerSelected 是什么?
  • AnswerSelected 是另一个事件,它被触发以通知包含所选答案控件的表单和答案 ID。
  • 它是否可能将您的事件处理程序分配给单选按钮一,然后将其重新分配给单选按钮二,然后将其重新分配给单选按钮三?您是否尝试过将每个单选按钮显式分配给单独的事件处理程序以进行测试?
  • 不,但我现在就试试。

标签: c# winforms user-controls lambda


【解决方案1】:

似乎在使用这样的 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));
     }
}

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

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

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

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2016-01-01
      • 1970-01-01
      • 2023-04-03
      • 2023-01-16
      • 2013-07-17
      • 2018-08-27
      • 1970-01-01
      • 2010-09-26
      • 1970-01-01
      相关资源
      最近更新 更多