2009-08-11 44 views
1

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

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

我设置编辑模式,这样,如果改变任何东西:

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

如果按Ctrl +单击会发生什么? – hannson 2009-08-14 13:12:36

+0

绝对没有:) – Gareth 2009-08-14 14:06:05

回答

2

这里有一个小的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)); 
       } 
      } 
     } 
    } 
} 
+0

太棒了!谢谢,这工作。我还发现,在文档中有一个名为'GetElementFromPoint'的方法,它使我不必存储元素位置。这里的主要想法是设置Cursor.Current,而不是Web浏览器控件的Cursor属性,这会导致它为我崩溃。 – Gareth 2009-08-17 06:58:53

+0

在我的睡眠中,我开始考虑一个需要考虑的问题。当用户实际编辑时,OffsetRectangles将移动。这可以通过使用两个隐藏的Web控件来解决。每次在EditMode中输入击键时,都会将内容复制到隐藏区域,然后重新创建“偏移”列表。让我知道你是否需要这个样本。 – 2009-08-17 17:00:43

0

我会检查,当用户将鼠标悬停在链接,以及可选显示在状态栏的东西。允许用户按住CTRL并单击链接打开它。

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

+0

谢谢安德鲁,是的,我已经玩过了,并通过鼠标光标找到它的元素。问题是用户需要手形光标,并且设置浏览器的游标属性不起作用。设置父控件(面板)的光标会导致某些东西变得不可靠,并且整个应用程序崩溃。理想情况下,我想要一些在浏览器控件中支持的东西,但如果这是最好的方式,那将会发生什么:) – Gareth 2009-08-14 14:05:49