WebBrowser control not auto-selecting text on doub

2019-02-17 11:38发布

问题:

NOTE: This is about the control's built-in behavior, not about creating a double-click event.

One of my projects uses the Windows.Forms.WebBrowser control as an editor and viewer for HTML. It has been working fine for years but suddenly I noticed that before when I would double-click it would automatically select the word which was clicked (this was not my code, just happened with the control).

Suddenly (not exactly sure when), double clicking text in the control (both in edit mode or in view mode) does nothing. It's hard to troubleshoot because it is not my code doing it, however, since I depended on this functionality in the past, it is now impacting my final product.

Any idea what would have recently changed (in Windows or in .Net) which would affected this (the same version of my app works fine in older Win7 but not in the most up-to-date Win7)? Also, how can I get the previous functionality back? Must I wire up my own double-click even on the DOM and then start parsing the text to manually select it (uh!)?

I've looked all over for the answer to this question but mostly I just see how to wire up to DOM events, nothing about recent changes which would cause the problem above). Any help would be greatly appreciated.

I'm using VS 2010, VB, Win7 x64, IE 10.0.6, .Net 3.5 (whatever the latest one is) when the problem happens (compiled so I doubt it is VS or VB).

When I run the exact same code (compiled) on Win7 x86 with IE 8 (Win7 Pro plain, with zero-updates installed) it works just fine.

After some further testing, on the Win7 x86 fresh install (where everything was fine) as soon as I install IE 10 and NOTHING ELSE the problem starts to happen. So, I'm pretty sure the problem lies with IE 10.

Steps to reproduce:

  1. Create a new VB.Net project in VS 2010, targetting .Net 3.5
  2. Create a usercontrol <--- this step is the key
  3. Add a webbrowser to the usercontrol
  4. Add this code to the usercontrol

    Public Sub LoadHTML(html As String)
        WebBrowser1.DocumentText = html
    
        Do Until WebBrowser1.ReadyState = WebBrowserReadyState.Complete
            Application.DoEvents()
        Loop
    
        WebBrowser1.Document.Body.SetAttribute("contentEditable", "false")
    End Sub
    
  5. Add that control to a form

  6. Add a button to the form with the following button.Click event:

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
        UserControl1.LoadHTML("<html><body>This is a test interesting is it not?</body></html>")
    End Sub
    
  7. Run the project and click the button

  8. Then, try to double-click the word "interesting" and notice it does not select.

If you throw the webbrowser control directly on the form, it will work fine. The problem is with the usercontrol (and it is only a problem after updating to IE10).

I can reproduce the problem using VS 2010 using .Net 3.5 and 4.0. I can reproduce the problem using VS 2012 using .Net 4.5.

回答1:

The problem is actually a bug in IE 10. This was confirmed by Microsoft here.

The saddest part is that they said they would not be fixing it any time soon (if ever) because it affects too few people (though it does affect thousands of my company's customers).



回答2:

Whilst this has been reported as a known issue in IE10 (none of the links reporting the bug that I've seen still work), it has not been fixed in any more recent versions (hence we're coming across the issue when finally migrating away from WinXP/IE8 to Win10/IE11).

Interestingly the best work around that I've found was from @John's posting of the same problem on the Chinese DataZX forum.

Basically the issue arises when certain properties of the System.Windows.Forms.WebBrowser control are set from the designer within a UserControl which makes its way into the UserControl.Designer.InitializeComponent() method. Moving these property assignments to occur later in the initialization process, eg: into the UserControl.Load event handler, resolves the problem and the double (+ triple) click behaviour of the control is restored.

Known properties causing this problem include (but others may also cause this or similar problems)

  • ScriptErrorsSuppressed
  • AllowWebBrowserDrop

So if either of these properties are set in the designer, move them to the Load event handler and the double click should now work as expected.

Eg (Problem code from UserControl.designer.vb)

Private Sub InitializeComponent()
    Me.WebBrowser1 = New System.Windows.Forms.WebBrowser()
    Me.SuspendLayout()
    '
    'WebBrowser1
    '
    Me.WebBrowser1.AllowWebBrowserDrop = False 'This line will cause the problem
    Me.WebBrowser1.Location = New System.Drawing.Point(20, 3)
    Me.WebBrowser1.MinimumSize = New System.Drawing.Size(20, 20)
    Me.WebBrowser1.Name = "WebBrowser1"
    Me.WebBrowser1.ScriptErrorsSuppressed = True  'This line will ALSO cause the problem
    Me.WebBrowser1.Size = New System.Drawing.Size(147, 138)
    Me.WebBrowser1.TabIndex = 0
End Sub

Comment out the lines above that cause the problem and replace with the following in the UserControl.vb

Private Sub UserControl_Load(sender As Object, e As EventArgs) Handles Me.Load
    'Setting these properties here does not cause any problems
    Me.WebBrowser1.AllowWebBrowserDrop = True 
    Me.WebBrowser1.ScriptErrorsSuppressed = False
    Me.WebBrowser1.DocumentText = "These are test words that you can attempt to double click"
End Sub


回答3:

I know this was asked a while back, but I too faced the same issue when I created a HTML Editor control and had IE 10 installed.

Here's how I resolved this in C#.Net:

// Add this to your Web Browsers ProgressChanged event
private void web_ProgressChanged(object sender, WebBrowserProgressChangedEventArgs e)
{
    // Detach the event handler before attaching
    web.Document.DetachEventHandler("ondblclick", Document_DoubleClick);

    // Now attach the event handler
    web.Document.AttachEventHandler("ondblclick", Document_DoubleClick);
}

// Add this to your project
private void Document_DoubleClick(object sender, EventArgs e)
{
    IHTMLSelectionObject sel = doc.selection as IHTMLSelectionObject;
    IHTMLTxtRange rng = sel.createRange() as IHTMLTxtRange;
    rng.expand("word");
    rng.select();
}

Now the double click will highlight the word under the mouse.



回答4:

The WebBrowser control does not play well with other controls, it's needs to be encapsulated (contained within) a Panel, isolated from other form controls.

I was using the WebBrowser control in a Tab Control and had the same issue. When adding a Panel within the tab then placing the WebBrowser within the panel, the issue went away.



回答5:

I'm late, but someone else may still be asking for help. I have this HtmlEditorControl and I wanted the DoubleClick works on Windows 10. In your WebBrowser.DocumentCompleted method add this code:

this.editorWebBrowser.Document.AttachEventHandler("ondblclick", (_object, _event) =>
        {
            //First check if the user has selected something, if not, move the current selection starting from the current location of the text cursor.
            if (string.IsNullOrEmpty(SelectedText.Trim()))
            {
                //All objects bellow are referenced, there is no need to assign them to the HtmlEditorControl again
                // define the selected range object
                mshtml.IHTMLSelectionObject selection;
                mshtml.IHTMLTxtRangerange = null;
                try
                {
                    // calculate the text range based on user selection
                    selection = _mshtmlDocument.selection;

                    if (selection.type.ToLower().Equals("text") || selection.type.ToLower().Equals("none"))
                    {
                        range = (mshtml.IHTMLTxtRange)selection.createRange();
                    }
                }
                catch (Exception)
                {
                    // have unknown error so set return to null
                    range = null;
                    return;
                }

                if (range == null)
                {
                    //error!!
                    return;
                }

                //Move the current selection one word back
                range.moveStart("word", -1);
                range.moveEnd("word", 1);
                range.select();
                if (range.text == null)
                {
                    //error!!
                    return;
                }
            }
        });


回答6:

I know it might be rather late to offer a solution, but I ended up modifying and rewriting a few javascript codes that I have stumbled upon and ended up making this, which hopefully may be useful for you.

This should help if anyone is still having this issue.

It is a cross browser, implementation as I work with a few other libraries for different browsers, but should be easy to remove the unnecessary code if you just want IE.

If you do try to implement this, I would recommend just minifying it and creating a js file in your application resources and then referencing it in the injection.

 Dim headElement As HtmlElement = browser.Document.GetElementsByTagName("head")(0)
        Dim scriptElement As HtmlElement = browser.Document.CreateElement("script")
        Dim element As IHTMLScriptElement = DirectCast(scriptElement.DomElement, IHTMLScriptElement)
        element.text = My.Resources.select_text_ie
        headElement.AppendChild(scriptElement)

This should be injected on DocumentCompleted event.



回答7:

Environment: VS2017 C#, .net framework 4.6, Win10. IE11 is installed. No manipulation on the FEATURE_BROWSER_EMULATION at the registry.

Drop a panel on a form, and then put a WebBrowser control on the panel. Double clicking on any element will not select the text on the html page.

If you don't use a panel and drop the WebBrowser directly on the form, it works fine. What if you need to use it with panels?

Create a simple user control with a WebBrowser on it, and exposed required events and properties of the WebBrowser. Put this user control on any panel and selecting text with double click will work as the way it should be.



回答8:

Insert <!DOCTYPE html> at the start of your file