如何在WebBrowser控件中显示字符串HTML内容?

70

我有一个 C# 的 win 应用程序。我将文本以 HTML 格式保存在我的数据库中,但我想要在 WebBrowser 控件中向用户显示它。如何将字符串 HTML 内容显示到 WebBrowser 控件中?


3
可能是c# webcontrol - 如何动态加载HTML?的重复问题。 - Malachi
2
这个问题似乎没有任何标签来指示您正在为哪个Windows平台构建此应用程序。 - 对于那些通过谷歌搜索进入此处并想要在Windows 10(或UWP)应用程序中执行此操作的人来说,浏览器控件(称为WebView)有一个名为NavigateToString的方法,您只需将HTML传递给它即可。 - BrainSlugs83
1
这是WebBrowser控件,而不是WebView - 因此适用于Windows Forms。 - eltiare
10个回答

117

试试这个:

webBrowser1.DocumentText =
    "<html><body>Please enter your name:<br/>" +
    "<input type='text' name='userName'/><br/>" +
    "<a href='http://www.microsoft.com'>continue</a>" +
    "</body></html>";

8
这对我只在第一次调用时有效。即使再加一个webbrowser1.Refresh()也不能帮助第二次调用。最终,这个链接对我有帮助:http://weblogs.asp.net/gunnarpeipman/archive/2009/08/15/displaying-custom-html-in-webbrowser-control.aspx - Thomas Weller

28

正如Thomas W.的评论所指出的一样-我差点没看到这条评论,但我也遇到了同样的问题,因此我认为值得重写为一个答案。

主要问题在于,在第一次将webBrowser1.DocumentText分配给某些HTML之后,随后的分配没有任何效果。

解决方法可以在Thomas提供的链接http://weblogs.asp.net/gunnarpeipman/archive/2009/08/15/displaying-custom-html-in-webbrowser-control.aspx中找到详细信息,但是为防止以后该页面无法使用,我在下面进行总结。

简而言之,由于webBrowser控件的工作方式,每次更改内容时必须导航到新页面。因此,作者提出了一种更新控件的方法:

private void DisplayHtml(string html)
{
    webBrowser1.Navigate("about:blank");
    if (webBrowser1.Document != null)
    {
        webBrowser1.Document.Write(string.Empty);
    }
    webBrowser1.DocumentText = html;
}

然而我发现在我的当前应用程序中,我从 if(webBrowser1.Document != null) 这行代码中得到了一个CastException异常。我不确定这是为什么,但我发现如果我用try catch包装整个if块,期望的效果仍然可以实现。参考:

private void DisplayHtml(string html)
{
    webBrowser1.Navigate("about:blank");
    try
    {
        if (webBrowser1.Document != null)
        {
            webBrowser1.Document.Write(string.Empty);
        }
    }
    catch (CastException e)
    { } // do nothing with this
    webBrowser1.DocumentText = html;
}

每次执行 DisplayHtml 函数时,我都会收到一个来自 if 语句的 CastException 异常,因此 if 语句的内容永远不会被执行。但是,如果我注释掉 if 语句以避免收到 CastException,那么浏览器控件就无法更新。我怀疑文档属性背后的代码还有其他副作用,尽管它也会抛出异常。

总之,我希望这对人们有所帮助。


1
你忘记包含这行代码 => 在处理展示给用户的内容之前,你应该将AllowNavigation属性设置为true。 - Ghasem
1
有趣。在我发表评论9年后,我找到了这个答案,因为我不记得如何正确地完成它。谢谢。也许你可以包括@AlexJolig的评论,因为这次正是这个问题。取消导航可以通过取消OnNavigation来完成。 - Thomas Weller

27

不要导航到空白页面,可以执行以下操作:

而不是导航到空白页面,你可以做:

webBrowser1.DocumentText="0";
webBrowser1.Document.OpenNew(true);
webBrowser1.Document.Write(theHTML);
webBrowser1.Refresh();

无需等待任何事件或其他事情。您可以查看MSDN中的OpenNew,而我已经在我的一个项目中测试了初始DocumentText分配并且它可以工作。


1
尽管看起来有些不专业,但这似乎是唯一能够始终正常工作的方法。 - Christian

6

由于某些原因,m3z提供的代码(使用DisplayHtml(string)方法)在我的情况下无法正常工作(除了第一次)。我总是从字符串中显示HTML。这是我与WebBrowser控件搏斗后的版本:

webBrowser1.Navigate("about:blank");
while (webBrowser1.Document == null || webBrowser1.Document.Body == null)
    Application.DoEvents();
webBrowser1.Document.OpenNew(true).Write(html);

每次都为我工作。希望它能帮助别人。


有趣。我想知道为什么我的解决方案对我有效而对你无效。我也不能说我尝试过你的解决方案,但它似乎是一个类似的概念。 - m3z
我不确定,但我怀疑是DoEvents()方法的问题。我认为当你导航到“about:blank”时,它需要一些时间(可能在另一个线程中),因此您的下一个“if”语句在我的PC上无法工作,因为1.它没有与Navigate()的效果进行线程同步,2.我的处理器速度/负载与您的不同,并且我在“if”处理方面没有那么幸运。更不用说DoEvents()可以在同一线程上执行某些操作。当然这只是一种猜测。另外,您没有OpenNew调用。有一件事我肯定知道,那就是我总是遇到WebBrowser的问题。 - P.W.
1
是的,我记得我不是很喜欢WebBrowser控件。随后,我找到并收藏了一个基于Webkit的替代控件,我打算在未来的项目中使用它。 - m3z
我将此标记为“已解决”,因为 Application.DoEvents(); 解决了我的问题。我正在使用 webBrowser1.DocumentText = myHtml; while (webBrowser1.DocumentText != myHtml) { Application.DoEvents(); } - gridtrak

4

我尝试过的简单解决方案是:

webBrowser1.Refresh();
var str = "<html><head></head><body>" + sender.ToString() + "</body></html>";
webBrowser1.DocumentText = str;

2

这里有一段代码。它可以在WebBrowser控件的任何后续html代码更改时正常运行(适用于我)。您可以根据自己的特定需求进行调整。

    static public void SetWebBrowserHtml(WebBrowser Browser, string HtmlText)
    {
        if (Browser != null)
        {
            if (string.IsNullOrWhiteSpace(HtmlText))
            {
                // Putting a div inside body forces control to use div instead of P (paragraph)
                // when the user presses the enter button
                HtmlText = 
                        @"<html>
                    <head>
                    <meta http-equiv=""Content-Type"" content=""text/html; charset=UTF-8"" />
                    </head>
                      <div></div>
                    <body>
                    </body>
                    </html>";
            }

            if (Browser.Document == null)
            {
                Browser.Navigate("about:blank");

                //Wait for document to finish loading
                while (Browser.ReadyState != WebBrowserReadyState.Complete)
                {
                    Application.DoEvents();
                    System.Threading.Thread.Sleep(5);
                }
            }

            // Write html code
            dynamic Doc = Browser.Document.DomDocument;
            Doc.open();
            Doc.write(HtmlText);
            Doc.close();


            // Add scripts here 
            /*  
            dynamic Doc = Document.DomDocument;
            dynamic Script = Doc.getElementById("MyScriptFunctions");
            if (Script == null)
            {
                Script = Doc.createElement("script");
                Script.id = "MyScriptFunctions";
                Script.text = JavascriptFunctionsSourcecode;
                Doc.appendChild(Script);
            }                 
            */



            // Enable contentEditable   
            /*  
            if (Browser.Document.Body != null)
            {
                if (Browser.Version.Major >= 9)
                    Browser.Document.Body.SetAttribute("contentEditable", "true");
            }             
             */

            // Attach event handlers
            // Browser.Document.AttachEventHandler("onkeyup", BrowserKeyUp);
            // Browser.Document.AttachEventHandler("onkeypress", BrowserKeyPress);
            // etc...
        }
    }        

1
对我不起作用 动态文档 = 浏览器.文档.DomDocument; // 目前为止还好 文档.打开(); // 开始出现问题,由于缺乏使用动态的参考 文档.写入(HtmlText); 文档.关闭(); - gg89

2

虽然这是一个老问题,但以下是我在这种情况下的首选操作。

If browser.Document IsNot Nothing Then
    browser.Document.OpenNew(True)
    browser.Document.Write(My.Resources.htmlTemplate)
Else
    browser.DocumentText = My.Resources.htmlTemplate
End If

请确保任何browser.Navigating事件不要取消"about:blank" URL。以下是一个示例事件,以完全控制WebBrowser导航。

Private Sub browser_Navigating(sender As Object, e As WebBrowserNavigatingEventArgs) Handles browser.Navigating

    Try
        Me.Cursor = Cursors.WaitCursor

        Select Case e.Url.Scheme

            Case Constants.App_Url_Scheme

                Dim query As Specialized.NameValueCollection = System.Web.HttpUtility.ParseQueryString(e.Url.Query)

                Select Case e.Url.Host

                    Case Constants.Navigation.URLs.ToggleExpander.Host

                        Dim nodeID As String = query.Item(Constants.Navigation.URLs.ToggleExpander.Parameters.NodeID)

                        :
                        :
                        <other operations here>
                        :
                        :

                End Select

            Case Else
                e.Cancel = (e.Url.ToString() <> "about:blank")

        End Select

    Catch ex As Exception
        ExceptionBox.Show(ex, "Operation failed.")
    Finally
        Me.Cursor = Cursors.Default
    End Try

End Sub

2

webBrowser.NavigateToString(yourString);


2
你的 webBrowser 控件上有 "NavigateToString" 方法吗?因为我的没有。 - MondayPaper
1
我的电脑上也不存在这个。 - m3z
@BrianS:我没有注意到。已删除评论。谢谢。 - Jack
NavigateToString只存在于WebBrowser控件的WPF版本中。 - Machman

0

m3z推荐的DisplayHtml(string html)对我很有用。

如果有人需要帮助,我还想提一下,最初我的HTML中有一些空格使HTML无效,因此文本显示为字符串。当我将HTML粘贴到Visual Studio时,这些空格被引入(在角括号周围)。因此,如果您尝试了本帖中提到的解决方案后,您的文本仍然显示为文本,则可能值得检查HTML语法是否正确。


0

更简单的是:

var html = "<html><body><h3>Hello</h3></body></html>";

BrowserCtrl.NavigateToString(html);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接