2009-08-11 13 views
1

編集モードでWindows.Forms WebBrowserコントロールを使用して、アプリケーション(.net 3.5 C#Windowsフォーム)でhtml編集を有効にしています。問題は、編集モードでは、html内のリンクがクリックできないことです。つまり、カーソルを置いてマウスカーソルを表示せずにクリックするだけで、そのリンクに移動するのではなく、その場所にカーソルが挿入されます。編集モードのWebBrowserコントロールのクリック可能なリンク

これは設計によるものですが、リンクを機能させたまま編集モードを有効にすることは可能ですか?私たちは、ユーザがコンテンツを編集できる間にローカルhtmlページのセットをナビゲートすることを望んでいます。

その変更はどちらかといえば、私は、次のように編集モードを設定しています:

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

Ctrl +クリックするとどうなりますか? – hannson

+0

絶対に何も:) – Gareth

答えて

2

ここで動作しているようです小さなWinフォームアプリケーションです。編集モードを設定すると、すべての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プロパティではなく、Cursorプロパティが原因でクラッシュするということです。 – Gareth

+0

私の睡眠では、あなたが考える必要がある問題について考えるようになった。ユーザーが実際に編集すると、OffsetRectanglesが移動します。これは、1つが隠されている2つのWebコントロールを持つことで修正できます。 EditModeにキーストロークが入力されるたびに、コンテンツを非表示にコピーし、Offsetリストを再作成します。このサンプルが必要な場合はお知らせください。 –

0

私は、ユーザーがリンクの上に置いたときのためにチェックし、必要に応じてステータスバーに何かを示すだろう。リンクを開くには、Ctrlキーを押しながらリンクをクリックします。

EDIT: これは便利で来ることがあります。http://www.codeproject.com/KB/mobile/browsermouseevents.aspx?msg=2732899

+0

ありがとうアンドリュー、はい、私はすでにその周りに遊んで、マウスカーソルの下に要素を見つけることによってそれを働かせました。問題は、ユーザがハンドカーソルを必要とし、ウェブブラウザのカーソルプロパティを設定しても機能しないことです。親コントロール(パネル)のカーソルを設定すると、何か不調なものになり、アプリケーション全体がクラッシュします。理想的には、私はブラウザのコントロール内でサポートされているものが欲しいですが、これが最良の方法であれば、何が起こるのでしょうか:) – Gareth

関連する問題