2

IE(6+)用のツールバーを書いています。のさまざまなサンプルバーを使用しました

codeproject.com ( http://www.codeproject.com/KB/dotnet/IE_toolbar.aspx )、および機能するツールバーを持っており、登録解除などを登録します。ツールバーに実行させたいのは、html ページ内の div を次のように強調表示することです。ユーザーのマウスがその div の上を移動します。これまでのところ、強調表示コードは機能しますが、div の名前 (存在する場合) をツールバーのラベルに表示したいと思います (マウスの移動などに応じて変化します)。

私の人生ではこれを実現することはできず、デバッグしようとするのは悪夢です。アセンブリは IE でホストされているため、そのコントロールを作成していないスレッドからラベルのテキストを更新しようとすることで (IE で) 例外が発生していると思われますが、IE で例外が発生しているため、見ないでください。

Invoke を使用してスレッドセーフな方法でコントロールを更新しようとする解決策はありますか? もしそうなら、どのように?

イベントコードは次のとおりです。

private void Explorer_MouseOverEvent(mshtml.IHTMLEventObj e)
{
      mshtml.IHTMLDocument2 doc = this.Explorer.Document as IHTMLDocument2;
      element = doc.elementFromPoint(e.clientX, e.clientY);
      if (element.tagName.Equals("DIV", StringComparison.InvariantCultureIgnoreCase))
      {
          element.style.border = "thin solid blue;";
          if (element.className != null)
          {
               UpdateToolstrip(element.className);
          }
      } 
      e.returnValue = false;
}

ツールバーのスレッドセーフな更新の試みは次のとおりです。

delegate void UpdateToolstripDelegate(string text);

public void UpdateToolstrip(string text)
{
     if (this.toolStripLabel1.InvokeRequired == false)
     {
         this.toolStripLabel1.Text = text;
     }
     else
     {
         this.Invoke(new UpdateToolstripDelegate(UpdateToolstrip), new object[] { text });
     }
}

どんな提案でも大歓迎です。

4

1 に答える 1

1

この問題を実際に再現することはできません (IE ツールバーのテスト プロジェクトを作成するのは少々手間がかかります) が、次の方法を試すことができます。

次のルーチンを public static (拡張メソッド) クラスに追加します。

public static void Invoke(this Control control, MethodInvoker methodInvoker)
{
    if (control.InvokeRequired)
        control.Invoke(methodInvoker);
    else
        methodInvoker();
}

そして、最初のブロックの同様のコードのセクションを次のように置き換えます。

if (element.className != null)
{
    this.Invoke(() => toolStripLabel1.Text = element.className);
}

これは、UI アプリケーションでスレッドセーフの問題を回避するための確実な方法です。

于 2008-10-28T20:08:19.840 に答える