2010-04-01 17 views
8

Tengo un proyecto en el que estoy trabajando en VS2005. He agregado un control WebBrowser. Agrego una página básica vacía para el controlC# WebBrowser control no aplica css

private const string _basicHtmlForm = "<html> " 
             + "<head> " 
             + "<meta http-equiv='Content-Type' content='text/html; charset=utf-8'/> " 
             + "<title>Test document</title> " 
             + "<script type='text/javascript'> " 
             + "function ShowAlert(message) { " 
             + " alert(message); " 
             + "} " 
             + "</script> " 
             + "</head> " 
             + "<body><div id='mainDiv'> " 
             + "</div></body> " 
             + "</html> "; 

private string _defaultFont = "font-family: Arial; font-size:10pt;"; 

private void LoadWebForm() 
{ 
    try 
    { 
     _webBrowser.DocumentText = _basicHtmlForm; 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

y luego añadir diversos elementos a través del DOM (usando _webBrowser.Document.CreateElement). Yo también estoy cargando un archivo css:

private void AddStyles() 
{ 
    try 
    { 
     mshtml.HTMLDocument currentDocument = (mshtml.HTMLDocument) _webBrowser.Document.DomDocument; 
     mshtml.IHTMLStyleSheet styleSheet = currentDocument.createStyleSheet("", 0); 

     TextReader reader = new StreamReader(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath),"basic.css")); 
     string style = reader.ReadToEnd(); 
     styleSheet.cssText = style; 
    } 
    catch(Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

Aquí está el contenido de la página css:

body { 
    background-color: #DDDDDD; 
} 

.categoryDiv { 
    background-color: #999999; 
} 

.categoryTable { 
    width:599px; background-color:#BBBBBB; 
} 

#mainDiv { 
    overflow:auto; width:600px; 
} 

El estilo de página se está cargando con éxito, pero los únicos elementos de la página que están siendo afectadas son las que están inicialmente en la página (body y mainDiv). También intenté incluir el CSS en un elemento de la sección del encabezado, pero solo afecta los elementos que están allí cuando se crea la página.

Así que mi pregunta es, ¿alguien tiene alguna idea sobre por qué el CSS no se está aplicando a los elementos que se crean después de cargar la página? También intenté no aplicar el CSS hasta después de agregar todos mis elementos, pero los resultados no cambian.

+0

he preguntado lo mismo. Siempre asumí que la creación de una página web de esa manera solo creaba una página obsoleta/muerta/estática, y que el motor de renderización dejaba de verificar los estilos a menos que un elemento dentro de la página hiciera que el procesador se "despertara". Pero estoy sacando eso de la nada. Acabo de aprender a agregar el CSS como lo primero en la cabeza al crear inicialmente un documento. –

+2

Sé que esto probablemente no ayuda en nada (por eso es un comentario), pero quería decirle por experiencia que el componente WebBrowser de C# es basura. Las cosas aparentemente triviales tienden a terminar como dolores de cabeza masivos y cuando no hace lo que quieres, a menudo terminas teniendo que ir al componente ActiveX subyacente ... que es un desastre por decir lo menos (~ 5 interfaces diferentes por completo desorganizado, que tiene conjuntos arbitrarios de funcionalidad). Recomiendo un componente de navegador diferente siempre que sea posible, por ejemplo, GeckoFX, basado en el motor Firefox. – Teekin

+2

Falta una información clave aquí: los elementos que está creando, los que no están siendo diseñados. Presumiblemente, está configurando el atributo de clase en '" categoryDiv "', '" categoryTable "', etc ... Pero eso no está explícitamente establecido en su pregunta. Teniendo en cuenta los resultados que describes, estoy mucho más inclinado a creer que hay un error en la creación de tu elemento que cualquier cosa directamente relacionada con la creación de tu hoja de estilo. Habiendo dicho eso, te das cuenta de que estás forzando a que la nueva hoja de estilos sea la primera en el documento (y por lo tanto de menor prioridad), ¿verdad? – Shog9

Respuesta

0

Sería bastante difícil de decir a menos que envíe un enlace de esto.

pero generalmente el mejor método para hacer cosas relacionadas con el estilo es que ya tiene el CSS en la página y en su código C# solo agrega identificadores o clases a los elementos para ver los efectos de estilos.

+0

He intentado tener el CSS en la página cuando lo creo en un elemento de estilo en el encabezado, y todavía solo afecta los elementos del cuerpo que están allí cuando se crea la página, no cualquiera que agregue a través del código. – JamesL

+0

¿tiene estilos en línea tal vez para que su css agregado pierda a su jerarquía de herencia? – XGreen

+0

no, no tengo ningún estilo en línea. – JamesL

0

He encontrado que las etiquetas generadas con el atributo de clase no obtienen sus estilos aplicados.

Esta es mi solución que se realiza después de que se genere el documento:

public static class WebBrowserExtensions 
{ 
    public static void Redraw(this WebBrowser browser) 
    { 
     string temp = Path.GetTempFileName(); 
     File.WriteAllText(temp, browser.Document.Body.Parent.OuterHtml, 
      Encoding.GetEncoding(browser.Document.Encoding)); 
     browser.Url = new Uri(temp); 
    } 
} 
+0

¿Puedes explicar esto un poco más?Tengo un div generado dinámicamente y tienen un atributo de clase. Ahora quiero configurar el display: ninguno para esta clase. ¿Alguna idea de cómo puedo hacerlo? – marifrahman

+0

@marifrahman No puedo ayudarte con eso, eso suena como algo que vale la pena [una pregunta propia] (http://stackoverflow.com/questions/ask) – hultqvist

0

utilizo el control similar en lugar de WebBrowser, me carga la página HTML con reglas de estilo "por defecto" y cambiar las reglas dentro del programa .

(Reintegro - mantenimiento, cuando tengo que añadir una regla, también necesito cambiar en el código)

' ---------------------------------------------------------------------- 
Public Sub mcFontOrColorsChanged(ByVal isRefresh As Boolean) 
    ' ---------------------------------------------------------------------- 
    ' Notify whichever is concerned: 
    Dim doc As mshtml.HTMLDocument = Me.Document 
    If (doc.styleSheets Is Nothing) Then Return 
    If (doc.styleSheets.length = 0) Then Return 
    Dim docStyleSheet As mshtml.IHTMLStyleSheet = CType(doc.styleSheets.item(0), mshtml.IHTMLStyleSheet) 
    Dim docStyleRules As mshtml.HTMLStyleSheetRulesCollection = CType(docStyleSheet.rules, mshtml.HTMLStyleSheetRulesCollection) 

    ' Note: the following is needed seperately from 'Case "BODY" 
    Dim docBody As mshtml.HTMLBodyClass = CType(doc.body, mshtml.HTMLBodyClass) 
    If Not (docBody Is Nothing) Then 
    docBody.style.backgroundColor = colStrTextBg 
    End If 

    Dim i As Integer 
    Dim maxI As Integer = docStyleRules.length - 1 
    For i = 0 To maxI 
    Select Case (docStyleRules.item(i).selectorText) 
     Case "BODY" 
     docStyleRules.item(i).style.fontFamily = fName ' "Times New Roman" | "Verdana" | "courier new" | "comic sans ms" | "Arial" 
     Case "P.myStyle1" 
     docStyleRules.item(i).style.fontSize = fontSize.ToString & "pt" 
     Case "TD.myStyle2" ' do nothing 
     Case ".myStyle3" 
     docStyleRules.item(i).style.fontSize = fontSizePath.ToString & "pt" 
     docStyleRules.item(i).style.color = colStrTextFg 
     docStyleRules.item(i).style.backgroundColor = colStrTextBg 
     Case Else 
     Debug.WriteLine("Rule " & i.ToString & " " & docStyleRules.item(i).selectorText) 
    End Select 

    Next i 

    If (isRefresh) Then 
    Me.myRefresh(curNode) 
    End If 

End Sub 
0

Podría ser que los objetos de la página existía en el momento de la página está siendo cargado, por lo que cada estilo se puede aplicar. El hecho de que agregue un nodo al árbol DOM no significa que pueda manipular y representar todos sus atributos dentro del navegador. los métodos anteriores parecen utilizar un enfoque que recarga la página (DOM), lo que sugiere que este puede ser el caso. En resumen, actualice la página después de agregar un elemento

0

Parece que phq ha experimentado esto. Creo que la forma en que abordaría es agregar una referencia a jquery a su documento html (desde el principio).

Luego, dentro de la página, crea una función javascript que acepte el identificador de elemento y el nombre de la clase a aplicar. Dentro de la función, use jquery para aplicar dinámicamente la clase en cuestión o para modificar el css directamente. Por ejemplo, use las funciones .addClass o .css de jquery para modificar el elemento.

A partir de ahí, en su código C#, después de agregar el elemento de invocar dinámicamente este javascript como se describe por Rick Strahl aquí: http://www.west-wind.com/Weblog/posts/493536.aspx

1

una solución consiste en inspeccionar el html antes de establecer la DocumentText e inyectar CSS en el lado del cliente. No configuro la propiedad url de control sino que obtengo el HTML a través de WebClient y luego configuro DocumentText. tal vez el establecimiento de DocumentText (o en su caso documento) después de manipular el DOM podría llegar a volver a representar adecuadamente

private const string CSS_960 = @"960.css"; 
private const string SCRIPT_FMT = @"<style TYPE=""text/css"">{0}</style>"; 
private const string HEADER_END = @"</head>"; 


public void SetDocumentText(string value) 
{ 
    this.Url = null; // can't have both URL and DocText 
    this.Navigate("About:blank"); 
    string css = null; 
    string html = value; 

    // check for known CSS file links and inject the resourced versions 
    if(html.Contains(CSS_960)) 
    { 
     css = GetEmbeddedResourceString(CSS_960); 
     html = html.Insert(html.IndexOf(HEADER_END), string.Format(SCRIPT_FMT,css)); 
    } 

    if (Document != null) { 
     Document.Write(string.Empty); 
    } 
    DocumentText = html; 
} 
6

hice una ligera modificación al método() sus AddStyles y funciona para mí. ¿De dónde lo llamas? Lo llamé desde "_webBrowser_DocumentCompleted".

Tengo que señalar que estoy llamando AddStyles después de modificar el DOM.

private void AddStyles() 
{ 
    try 
    { 
     if (_webBrowser.Document != null) 
     { 
      IHTMLDocument2 currentDocument = (IHTMLDocument2)_webBrowser.Document.DomDocument; 

      int length = currentDocument.styleSheets.length; 
      IHTMLStyleSheet styleSheet = currentDocument.createStyleSheet(@"", length + 1); 
      //length = currentDocument.styleSheets.length; 
      //styleSheet.addRule("body", "background-color:blue"); 
      TextReader reader = new StreamReader(Path.Combine(Path.GetDirectoryName(Application.ExecutablePath), "basic.css")); 
      string style = reader.ReadToEnd(); 
      styleSheet.cssText = style; 

     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message); 
    } 
} 

Aquí es mi manejador DocumentCompleted (añadí algunos estilos de basic.css para la prueba):

private void _webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) 
{ 
    HtmlElement element = _webBrowser.Document.CreateElement("p"); 
    element.InnerText = "Hello World1"; 
    _webBrowser.Document.Body.AppendChild(element); 

    HtmlElement divTag = _webBrowser.Document.CreateElement("div"); 
    divTag.SetAttribute("class", "categoryDiv"); 
    divTag.InnerHtml = "<p>Hello World2</p>"; 
    _webBrowser.Document.Body.AppendChild(divTag); 


    HtmlElement divTag2 = _webBrowser.Document.CreateElement("div"); 
    divTag2.SetAttribute("id", "mainDiv2"); 
    divTag2.InnerHtml = "<p>Hello World3</p>"; 
    _webBrowser.Document.Body.AppendChild(divTag2); 

    AddStyles(); 
} 

Esto es lo que me pasa (modificado el estilo para que sea tan feo como un solo hombre siendo pueden esperar para que sea: D):

alt text http://www.freeimagehosting.net/uploads/2e372f7276.png

+0

solo un par de comentarios, para mí el uso de este código con un control webbrowser wpf tuve que usar WebControl.Document como mshtml.HTMLDocument; para obtener el documento y apliqué el estilo en el evento Navegado. gracias – Kezza

+1

@ LifeH2O: Misión cumplida. :) –

Cuestiones relacionadas