C#WebBrowser控件不应用css

我有一个我正在VS2005中工作的项目。 我添加了一个WebBrowser控件。 我向控件添加了一个基本的空页面

private const string _basicHtmlForm = " " + " " + " " + "Test document " + " " + "function ShowAlert(message) { " + " alert(message); " + "} " + " " + " " + "
" + "
" + " "; private string _defaultFont = "font-family: Arial; font-size:10pt;"; private void LoadWebForm() { try { _webBrowser.DocumentText = _basicHtmlForm; } catch(Exception ex) { MessageBox.Show(ex.Message); } }

然后通过dom添加各种元素(使用_webBrowser.Document.CreateElement)。 我也在加载一个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); } } 

这是css页面内容:

 body { background-color: #DDDDDD; } .categoryDiv { background-color: #999999; } .categoryTable { width:599px; background-color:#BBBBBB; } #mainDiv { overflow:auto; width:600px; } 

样式页面已成功加载,但页面上受影响的唯一元素是最初位于页面(body和mainDiv)中的元素。 我也尝试将css包含在标题部分的元素中,但它仍然只影响创建页面时的元素。

所以我的问题是,有没有人知道为什么css没有应用于页面加载后创建的元素? 在添加完所有元素之后,我也尝试过不应用css,但结果不会改变。

我对你的AddStyles()方法进行了一些修改,它对我有用。 你在哪里叫它? 我从“_webBrowser_DocumentCompleted”调用它。

我必须指出,在修改DOM之后,我正在调用AddStyles。

 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); } } 

这是我的DocumentCompleted处理程序(我在basic.css中添加了一些样式用于测试):

 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 = "

Hello World2

"; _webBrowser.Document.Body.AppendChild(divTag); HtmlElement divTag2 = _webBrowser.Document.CreateElement("div"); divTag2.SetAttribute("id", "mainDiv2"); divTag2.InnerHtml = "

Hello World3

"; _webBrowser.Document.Body.AppendChild(divTag2); AddStyles(); }

这就是我得到的(修改了风格,使它像一个人可以希望做到的丑陋:D):

alt text http://sofzh.miximages.com/c%23/www.freeimagehosting.net

一种解决方案是在设置DocumentText之前检查html并在客户端注入CSS。 我没有设置控制url属性,而是通过WebCLient获取HTML,然后设置DocumentText。 也许在操作DOM之后设置DocumentText(或在你的案例文档中)可以让它正确地重新渲染

 private const string CSS_960 = @"960.css"; private const string SCRIPT_FMT = @""; private const string HEADER_END = @""; 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; } 

除非你发送这个链接,否则很难说。

但通常做风格相关的最佳方法是你已经在页面中使用了css,而在你的c#代码中你只需要为元素添加id或类来查看样式效果。

我发现带有class属性的生成标签没有应用它们的样式。

这是我在生成文档后完成的解决方法:

 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); } } 

我使用类似的控件而不是WebBrowser,我使用“默认”样式规则加载HTML页面,并更改程序中的规则。

(DrawBack – 维护,当我需要添加规则时,我还需要在代码中更改它)

 ' ---------------------------------------------------------------------- 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 

可能是页面加载时页面上的对象是EXIST,因此可以应用每种样式。 仅仅因为你向DOM树添加一个节点,并不意味着它可以在浏览器中操作和渲染它的所有属性。 上面的方法似乎使用重新加载页面(DOM)的方法,这表明可能是这种情况。 简而言之,在添加元素后刷新页面

听起来好像phq经历过这一点。 我认为我接近的方法是在你的html文档中添加对jquery的引用(从一开始)。

然后在页面内部创建一个javascript函数,该函数接受元素id和要应用的类的名称。 在函数内部,使用jquery动态地应用有问题的类或直接修改css。 例如,使用jquery的.addClass或.css函数来修改元素。

从那里,在您的C#代码中,在您添加元素之后,动态调用此javascript,如Rick Strahl所述: http : //www.west-wind.com/Weblog/posts/493536.aspx