首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C# WinForms应用程序中的CefSharp浏览器未触发任何鼠标事件

C# WinForms应用程序中的CefSharp浏览器未触发任何鼠标事件
EN

Stack Overflow用户
提问于 2021-02-21 05:31:04
回答 1查看 1.2K关注 0票数 1

因此,我的最终目标是检测用户何时在网页上按下了鼠标左键(任何元素,如按钮、图像等)。这样,我就可以运行一些javascript,根据用户点击的位置获取所需的适当html数据。

如果不进一步,我已经被困在第一部分,我的浏览器控件似乎没有触发任何与鼠标相关的事件。然而,它似乎提供了MouseDown、MouseEnter、MouseClick等处理程序,但似乎不会触发它们中的任何一个。

我尝试使用一个textbox控件和一个按钮来设置一个简单的WinForms测试项目。手动添加浏览器,如下所示:

代码语言:javascript
运行
复制
using CefSharp;
using CefSharp.WinForms;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace myProject
{
    public partial class Form1 : Form
    {
        public ChromiumWebBrowser browser;
        private string myUrl = "https://www.google.com/";
        
        public Form1()
        {
            InitializeComponent();
            InitializeChromium();

            browser.MouseDown += ChromeBrowser_MouseDown;
        }

        public void InitializeChromium()
        {
            browser = new ChromiumWebBrowser(myUrl);

            browser.Location = new Point(26, 59);
            browser.Size = new Size(988,566);
            browser.Dock = DockStyle.None;
            this.Controls.Add(browser);

        }

        private void ChromeBrowser_MouseDown(object sender, MouseEventArgs e)
        {
            //This handler never gets fired!!!

            if (e.Button == MouseButtons.Left)
            {
                //get value from html element
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            browser.Load(addressBar.Text);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Cef.Shutdown();
        }
    }
}

我试着浏览了一大堆网站,包括官方网站有关处理程序的文档,但似乎不知道我是否必须做更复杂的事情来侦听和处理鼠标事件,或者我应该能够像实现任何其他事件一样实现它。

有人能帮我修复我的MouseDown事件处理程序吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-02 07:48:09

花了一段时间,但最终还是贴出了我自己的答案!希望其他人会发现这一点很有用。

感谢@amaitland在评论中指出,CefSharp浏览器不会触发任何键盘或鼠标事件,也感谢您发布此链接这最终让我找到了我的答案。

解决方法是注入一些Javascript (当浏览器加载完框架后),然后侦听和检测任何鼠标/键盘事件。一旦触发,您的Javascript就会调用CefSharp.PostMessage(data);它在自己的线程上通知CefSharp浏览器,并返回任何有用的data(取决于您的脚本)。

初始化事件处理程序

添加browser.JavascriptMessageReceived += Browser_JavascriptMessageReceived;&browser.FrameLoadEnd += Browser_FrameLoadEnd;初始化将激活必要的钩子,如下所示(遵循我最初的示例):

代码语言:javascript
运行
复制
public void InitializeChromium()
        {
            browser = new ChromiumWebBrowser(myUrl);

            browser.Location = new Point(26, 59);
            browser.Size = new Size(988,566);
            browser.Dock = DockStyle.None;
            this.Controls.Add(browser);

            browser.JavascriptMessageReceived += Browser_JavascriptMessageReceived;
            browser.FrameLoadEnd += Browser_FrameLoadEnd;
        }

实现事件处理程序

现在剩下的工作就是通过添加以下代码来实现这些事件处理程序:

代码语言:javascript
运行
复制
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
        {
            if (e.Frame.IsMain)
            {
                browser.ExecuteScriptAsync(@"
                    document.addEventListener('click', function(e) {
                        var parent = e.target.parentElement;

                        // run some validation with if(){..}
                        // some more javascript

                        CefSharp.PostMessage(parent.outerHTML);
                    }, false);
                ");
            }
        }

        private void Browser_JavascriptMessageReceived(object sender, JavascriptMessageReceivedEventArgs e)
        {
            if (e.Message != null)
            {
                // Extract data from e.Message.toString() and use delegates/callbacks/Invokes 
                // to reference the main UI thread for updating the necessary controls.
            }
        }

加载网页/框架后,Browser_FrameLoadEnd处理程序将运行,然后将注入您的自定义Javascript。Browser_JavascriptMessageReceived只有在以下情况下才会触发处理程序CefSharp.PostMessage(data);是从你的Javascript中调用的。

此外,不是使用document.body.onmouseup在javascript中,如下面的建议所示:

此链接,我选择了

document.addEventListener('click', function(e)以便获得目标/点击的元素。在我的例子中,这对于获取所需的数据是至关重要的,这些数据属于这个被单击元素的parentElement。(请记住,我的实际案例是针对不同于google的网站的,正如我的示例所建议的那样)

完整示例代码

完整的扩展示例代码如下所示:

代码语言:javascript
运行
复制
using CefSharp;
using CefSharp.WinForms;
using System;
using System.Drawing;
using System.Windows.Forms;

namespace myProject
{
    public partial class Form1 : Form
    {
        public ChromiumWebBrowser browser;
        private string myUrl = "https://www.google.com/";
        
        public Form1()
        {
            InitializeComponent();
            InitializeChromium();
        }

        public void InitializeChromium()
        {
            browser = new ChromiumWebBrowser(myUrl);

            browser.Location = new Point(26, 59);
            browser.Size = new Size(988,566);
            browser.Dock = DockStyle.None;
            this.Controls.Add(browser);

            browser.JavascriptMessageReceived += Browser_JavascriptMessageReceived;
            browser.FrameLoadEnd += Browser_FrameLoadEnd;
        }

        private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
        {
            if (e.Frame.IsMain)
            {
                browser.ExecuteScriptAsync(@"
                    document.addEventListener('click', function(e) {
                        var parent = e.target.parentElement;

                        // run some validation with if(){..}
                        // some more javascript

                        CefSharp.PostMessage(parent.outerHTML);
                    }, false);
                ");
            }
        }

        private void Browser_JavascriptMessageReceived(object sender, JavascriptMessageReceivedEventArgs e)
        {
            if (e.Message != null)
            {
                // Extract data from e.Message.toString() and use delegates/callbacks/Invokes 
                // to reference the main UI thread for updating the necessary controls.
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            browser.Load(addressBar.Text);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            Cef.Shutdown();
        }
    }
}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66296771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档