2009-11-19 17 views
5

Tengo un problema frustrante. Aquí hay una versión simplificada de lo que estoy haciendo:El control WPF WebBrowser no entra en modo de diseño cuando se cambia la propiedad del documento

Un UserControl en C# contiene una barra de herramientas y un objeto WebBrowser incrustado. La barra de herramientas contiene un botón "Editar", que al hacer clic establece el control del navegador web en modo de diseño. Otro botón, "Cancelar", desactiva el modo de diseño.

Pseudocódigo (muy simplificada):

public void SetDesignMode(bool dm) { 
    IHTMLDocument2 doc = webBrowser.Document as IHTMLDocument2; 
    if (dm) doc.designMode = "On"; 
    else doc.designMode = "Off"; 
    _designMode = dm; 
    ReloadDocument(); // setting designmode clears the document element, so it must be reloaded 
} 

public void OnLoadCompleted() { 
    IHTMLDocument2 doc = webBrowser.Document as IHTMLDocument2; 
    if (!_documentLoaded) { 
    if (_designMode) doc.designMode = "On"; 
    else doc.designMode = "Off"; 
    ReloadDocument(); 
    _documentLoaded = true; 
    } 
} 

public void ReloadDocument() { 
    _documentLoaded = false; 
    // code that navigates to the document 
} 

El problema: Si hago clic en la página web que aparece, y luego en el botón "Editar", el control WebBrowser no se convertirá editable . El puntero del mouse al aspirar imágenes/enlaces muestra los punteros del mouse de navegación del navegador web, no los de edición. Si hago clic en el texto, el símbolo de intercalación no se mostrará.

La depuración revela que la propiedad designMode en el documento está realmente activada en esta situación, pero el control se comporta como si estuviera en "Off".

Si No clic en la página web antes de hacer clic en el botón "Editar", todo funciona como se esperaba.

Elaboración: Si hago clic en el botón "Cancelar" cuando el control está en modo de diseño, consigo el (mal) comportamiento correspondiente, si el documento se ha hecho clic en

Basta con hacer clic en ". Editar ", luego" Cancelar ", luego" Editar ", etc. sin hacer clic en el documento funciona bien (la prueba de mouse muestra los punteros del mouse adecuados, y obtengo navegación o edición de enlaces dependiendo del modo de diseño si hago clic en un vínculo de el documento mostrado).

He intentado varias técnicas para asegurarme de que otro control obtiene el foco antes de cambiar la propiedad designMode, pero no hace ninguna diferencia. He buscado en MSDN y en la mitad del internet conocido y no he encontrado ninguna mención de este tipo de problema. Voltear la propiedad designMode de esta manera parece ser bastante inusual.

Un dato más de información: estoy configurando eventos de documentos mediante el asesoramiento del documento con un receptor implementado por el control de usuario. Dudo que esto tenga alguna relación con el problema, pero lo he incluido aquí por el hecho de estar completo. Actualización: Desactivar esto no cambia nada con respecto al problema.

¿Alguien reconoce este problema?

Actualización: He solucionado el problema volviendo a crear el control del navegador web en SetDesignMode(). Es una solución fea, pero funciona y realmente se ve bien. Sin embargo, estoy muy interesado en cualquier comentario sobre este problema. Creo que es un error en MSHTML.

Respuesta

8

No estoy seguro si tuvimos exactamente el mismo problema, pero supongo que mi solución también debería funcionar para usted.

El problema básico parece ser que x64 restableció el atributo designMode, como se indica en this article. En mi caso, lo configuré en "Activado" después de crear instancias del navegador web, pero en el evento DocumentCompleted, fue "Heredar" nuevamente. Volver a establecerlo como "Activado" en DocumentCompleted lo hace editable, pero borra el documento. Al establecer DocumentText, se reinicia todo el ciclo de destrucción.

Así que una solución que encontré fue que se abstengan de establecer el DocumentText, en lugar de eso creó un documento vacío, a continuación, establecer el cuerpo (que en este punto ya no es nulo) InnerHtml propiedad:

doc.designMode = "On"; // enable editing 

// designMode change resets the document, create it anew 
webBrowser1.Document.Write("<html><body></body></html>") 
webBrowser1.Document.Body.InnerHtml = "myDocumentText" 

Obviamente, esto funciona solo si tiene el texto listo, y no si está navegando hacia una URL. Sin embargo, hay otra solución que funcionó para mí, que parece más fácil y segura. Lo encontré en this answer por LaughingJohn. Supongo que la primera línea depende de su aplicación, usted tenía IHTMLDocument directamente en webBrowser1.Document.

doc = webBrowser1.Document.DomDocument as IHTMLDocument2; 
if (doc != null && doc.body != null) 
    ((HtmlBody)doc.body).contentEditable = "true"; 
+0

Ambos métodos funcionan, gracias. Sin embargo; El primer método de alguna manera puso mi "Deshacer" (Ctrl-Z/ExecCommand ("Deshacer" ...)) fuera de acción. En el segundo método, los cambios no se reflejan en webBrowser.DocumentText por algún motivo. Pude extraerlo a través de webBrowser.Dourment.Body.InnerHtml y solucioné el problema. – Natan

0

Me parece que el WebBrowser se enfoca al hacer clic en él y de alguna manera se aferra a él. Intente esto: haga clic en WebBrowser, luego presione la tecla Tab en el teclado (que debe aleje el foco del WebBrowser) y luego vea si puede hacer clic en los botones.

Si puede, intente adjuntar un controlador al evento Button.MouseEnter y llame al ((Button)sender).Foucs() para enfocar el botón mediante programación.

Cuestiones relacionadas