WebBrowser 控件 onpropertychange 事件的事件处理程序 - sender 和 e 对象为 null

发布于 2025-01-03 14:32:39 字数 1125 浏览 5 评论 0原文

在 C# 中,我在服务器端线程中运行 WebBrowser (WB) 控件,并希望监视(侦听)“onpropertychange”事件。我可以成功附加一个在属性更改时执行的 .NET 委托签名方法,但每次调用 qEventHndlr 时 sender 和 e 对象均为 null,因此,我不知道哪个属性发生了更改触发事件。 el 是一个 HTMLElement,它在 foreach 循环中迭代,以将事件处理程序附加到每个要监视(侦听)的元素。

el.AttachEventHandler("onpropertychange", qEventHndlr);     // in the foreach loop
public void qEventHndlr(Object sender, EventArgs e) {…}     // the event handler

文档表明EventArgs类; “此类不包含事件数据;引发事件时不将状态信息传递给事件处理程序的事件使用它。如果事件处理程序需要状态信息,则应用程序必须从此类派生一个类来保存数据”。 似乎(我不确定也没有测试过)发件人仅填充了 WB 事件的子集,而不是 onpropertychange。

因此,我随后想到,如果无法在 send 或 e 对象中获取标识符信息,我可以在 AttachEventHandler 中使用匿名方法,然后将唯一的运行时可编程字符串参数传递给嵌入在事件处理程序方法调用中的方法。

el.AttachEventHandler("onpropertychange", delegate(Object sender, EventArgs e) { anonoMeth(elID); });
public void anonoMeth(string specificProperty) {..}

然而,编译器接受了该语法,即使 elID 字符串在 foreach 循环中发生更改,也仅使用第一个迭代值,因此当每个 onpropertychange 事件调用 anonoMeth(string SpecificProperty) 时,specicProperty 具有相同的值,因为相同的 elID被附加到相应的元素。

我还没有尝试过扩展方法,想发布这篇文章来看看是否有人遇到过类似的挑战(希望有解决方案)。除非绝对必要,否则我宁愿不诉诸 C++。

In C#, I am running the WebBrowser (WB) control in a server-side thread and want to monitor (listen) for "onpropertychange" events. I can successfully attach a .NET delegate signature method that is executed when a property changes, but the sender and e objects are both null in every call to qEventHndlr, therefore, I don't know which property changed to fire the event. el is an HTMLElement that is iterated in a foreach loop to attach the eventhandler to each element to monitor (listen).

el.AttachEventHandler("onpropertychange", qEventHndlr);     // in the foreach loop
public void qEventHndlr(Object sender, EventArgs e) {…}     // the event handler

The documentation indicates that the EventArgs class; "This class contains no event data; it is used by events that do not pass state information to an event handler when an event is raised. If the event handler requires state information, the application must derive a class from this class to hold the data."
It also seems (I'm not certain and haven't tested) that sender is only populated for a subset of WB events and not onpropertychange.

So, I then thought that if I can't get identifier information in the send or e objects, I could use an anonymous method in the AttachEventHandler and then pass a unique runtime programmable string parameter to a method embedded in the event handler method call.

el.AttachEventHandler("onpropertychange", delegate(Object sender, EventArgs e) { anonoMeth(elID); });
public void anonoMeth(string specificProperty) {..}

The compiler accepted the syntax, however, even though the elID string changes in the foreach loop, only the first iteration value is used so that when anonoMeth(string specificProperty) is called with each onpropertychange event, specificProperty has the same value because the same elID was attached to the respective element.

I haven't tried Extension Methods yet and wanted to get this posted to see if anyone has encountered similar challenges (and hopefully has a solution). I prefer not to resort to C++ unless I absolutely have to.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

拿命拼未来 2025-01-10 14:32:39

您需要在事件处理程序中将 sender 转换为适当类型的对象(在您的情况下为 HTMLElement)。

试试这个例子的尺寸:

namespace WebBrowserEventTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            webBrowserTest.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowserTest_DocumentCompleted);
            webBrowserTest.Navigate("http://mondotees.com");
        }

        private void webBrowserTest_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            foreach(HtmlElement el in webBrowserTest.Document.GetElementsByTagName("div"))
            {
                el.AttachEventHandler("onpropertychange", delegate { testEventHandler(el, EventArgs.Empty); });
            }

            foreach (HtmlElement el in webBrowserTest.Document.GetElementsByTagName("div"))
            {
                el.Name = "test";
            }
        }

        public void testEventHandler(object sender, EventArgs e)
        {
            var he = (HtmlElement)sender;
        }
    }
}

You need to cast your sender to an object of the appropriate type (an HTMLElement in your case) in your event handler.

Try this example on for size:

namespace WebBrowserEventTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            webBrowserTest.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowserTest_DocumentCompleted);
            webBrowserTest.Navigate("http://mondotees.com");
        }

        private void webBrowserTest_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            foreach(HtmlElement el in webBrowserTest.Document.GetElementsByTagName("div"))
            {
                el.AttachEventHandler("onpropertychange", delegate { testEventHandler(el, EventArgs.Empty); });
            }

            foreach (HtmlElement el in webBrowserTest.Document.GetElementsByTagName("div"))
            {
                el.Name = "test";
            }
        }

        public void testEventHandler(object sender, EventArgs e)
        {
            var he = (HtmlElement)sender;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文