【问题标题】:Clickable links in WebBrowser control in edit mode编辑模式下 WebBrowser 控件中的可点击链接
【发布时间】:2009-08-17 04:36:08
【问题描述】:

我在编辑模式下使用 Windows.Forms WebBrowser 控件在我们的应用程序(.net 3.5 C# windows 窗体)中启用 html 编辑。问题是在编辑模式下,html 中的链接不可点击(即,将鼠标悬停在它们上方不会显示手鼠标光标,点击它们只会将光标插入该位置,而不是导航到该链接)。

我意识到这是设计使然,但是否可以在保持链接正常运行的同时启用编辑模式?我们希望用户在能够编辑内容的同时浏览一组本地 html 页面。

我正在设置这样的编辑模式,如果它有任何改变:

webBrowser.Document.ExecCommand("EditMode", false, null);

【问题讨论】:

  • Ctrl+点击会发生什么?

标签: c# winforms webbrowser-control


【解决方案1】:

这是一个似乎可以工作的小型 WinForm 应用程序。设置编辑模式时,它记录所有A标签的所有链接位置,然后检查鼠标的光标位置。如果有框架或标签嵌套,我不确定 OffsetRectangle 是否给出正确的值,但应用程序中的示例 html 有效。

如果需要,可以修改它以从其他标签中捕获 onclick 等。

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        private readonly Dictionary<Rectangle, Uri> _links = new Dictionary<Rectangle, Uri>();
        private readonly Regex _reLink = new Regex("href=['\"](?<link>.*?)['\"]");

        private const string _html =
            "<html><body><br><div style='top:20px;left:50px;border:solid 1px red'><a href='http://www.cnn.com'>CNN</a></div><br><font size='14'>xx</font><a href='http://stackoverflow.com'>stackoverflow</a></body></html>";

        private bool _isEditMode;

        public Form1()
        {
            InitializeComponent();
            webBrowser1.DocumentText = _html;
            webBrowser1.Document.Click += Document_Click;
            webBrowser1.Document.MouseMove += Document_MouseMove;
        }

        private void Document_MouseMove(object sender, HtmlElementEventArgs e)
        {
            if (!_isEditMode) return;
            ChangeCursorIfOverLink(e);
        }

        private void ChangeCursorIfOverLink(HtmlElementEventArgs e)
        {
            foreach (KeyValuePair<Rectangle, Uri> link in _links)
            {
                if (CursorWithinControl(e, link.Key))
                {
                    if (Cursor.Current != Cursors.Hand)
                        Cursor.Current = Cursors.Hand;
                    return;
                }
            }
            Cursor.Current = Cursors.Default;
        }

        private void Document_Click(object sender, HtmlElementEventArgs e)
        {
            NavigateLinkInEditMode(e);
        }

        private void NavigateLinkInEditMode(HtmlElementEventArgs e)
        {
            if (_isEditMode)
            {
                foreach (KeyValuePair<Rectangle, Uri> link in _links)
                {
                    if (CursorWithinControl(e, link.Key))
                    {
                        webBrowser1.Navigate(link.Value);
                        return;
                    }
                }
            }
        }

        private bool CursorWithinControl(HtmlElementEventArgs e, Rectangle rectangle)
        {
            return e.MousePosition.X >= rectangle.Left
                   && e.MousePosition.X <= rectangle.Left + rectangle.Width
                   && e.MousePosition.Y >= rectangle.Top
                   && e.MousePosition.Y <= rectangle.Top + rectangle.Height;
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RecordLinkPositions();
            webBrowser1.Document.ExecCommand("EditMode", false, null);
            webBrowser1.DocumentText = _html;
            _isEditMode = true;
        }

        private void RecordLinkPositions()
        {
            foreach (HtmlElement element in webBrowser1.Document.All)
            {
                if (element.TagName == "A")
                {
                    string url = _reLink.Match(element.OuterHtml).Groups["link"].Value;
                    _links.Add(element.OffsetRectangle, new Uri(url));
                }
            }
        }
    }
}

【讨论】:

  • 太棒了!谢谢,这行得通。我还发现文档上有一个名为GetElementFromPoint 的方法,它使我不必存储元素位置。这里的主要思想是您正在设置 Cursor.Current,而不是 Web 浏览器控件的 Cursor 属性,这导致它崩溃。
  • 在睡梦中,我开始思考一个你需要思考的问题。当用户实际编辑时,OffsetRectangles 将移动。这可以通过有两个 web 控件来解决,其中一个是隐藏的。每次在 EditMode 中输入击键时,您将内容复制到隐藏,并重新创建偏移列表。如果您需要这个样本,请告诉我。
【解决方案2】:

我会检查用户何时将鼠标悬停在链接上,并可选择在状态栏中显示某些内容。允许用户CTRL+点击链接打开它。

编辑: 这可能有用:http://www.codeproject.com/KB/mobile/browsermouseevents.aspx?msg=2732899

【讨论】:

  • 谢谢 Andrew,是的,我已经玩过这个,并通过在鼠标光标下找到元素来让它工作。问题是用户想要一个手形光标,而设置 webbrowser 的光标属性不起作用。设置父控件(面板)的光标会导致出现问题,整个应用程序崩溃。理想情况下,我想要浏览器控件中支持的东西,但如果这是最好的方法,那就是必须发生的事情:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-12
  • 1970-01-01
  • 2011-06-27
相关资源
最近更新 更多