2009-08-11 77 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