1

私は、WebBrowserコントロールを使用してHTMLをレンダリングおよび操作するために、WindowsフォームのUserControlに取り組んでいます。コンテンツの一部は、コントロール内からクリックイベントをキャプチャするために必要ないくつかのラジオボタンです。したがって、webBrowserのDocumentCompletedイベントで、ラジオボタンにonClickイベントをアタッチしています。ラジオボタンの1つをクリックするまで、これはすべて機能しているようです。コードをステップ実行し、各ラジオボタンにデリゲートがアタッチされている場合でも、実際には最後のラジオボタンのみがイベントをアタッチしているようです。

これは、デリゲートを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);
 }

AnswerSelectedの委任とイベント

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

入力ボタンの文字列。

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

2 に答える 2

1

このようなラムダを使用すると、オブジェクトを参照するために使用される変数が失われるようです。このようにイベントを添付すると

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

要素の数よりも大きくなるという問題があります(これは私を困惑させます)。

ただし、この方法でイベントを添付すると

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 に答える