How to Display the String HTML Contents into Webbrowser Control

Displaying html from string in WPF WebBrowser control

The WebBrowser has a NavigateToString method that you can use to navigate to HTML content. If you want to be able to bind to it, you can create an attached property that can just call the method when the value changes:

public static class BrowserBehavior
{
public static readonly DependencyProperty HtmlProperty = DependencyProperty.RegisterAttached(
"Html",
typeof(string),
typeof(BrowserBehavior),
new FrameworkPropertyMetadata(OnHtmlChanged));

[AttachedPropertyBrowsableForType(typeof(WebBrowser))]
public static string GetHtml(WebBrowser d)
{
return (string)d.GetValue(HtmlProperty);
}

public static void SetHtml(WebBrowser d, string value)
{
d.SetValue(HtmlProperty, value);
}

static void OnHtmlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
WebBrowser wb = d as WebBrowser;
if (wb != null)
wb.NavigateToString(e.NewValue as string);
}
}

And you would use it like so (where lcl is the xmlns-namespace-alias):

<WebBrowser lcl:BrowserBehavior.Html="{Binding HtmlToDisplay}" />

How to show an HTML string in WebBrowser control when the address is about:blank

A document Refresh simply reloads the current page, so the Navigating, Navigated, and DocumentCompleted events do not occur when you call the Refresh method.

Using Navigating or Navigated event you should check if the browser is navigating or navigated to about:blank then disable the ways that user can refresh page, including browser shortcuts, browser context menu or any other point like custom toolbar buttons and context menus you created or refresh.

For other urls, enable them again.

private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
var state = (e.Url.ToString().ToLower() == "about:blank");
this.webBrowser1.WebBrowserShortcutsEnabled = !state;
this.webBrowser1.IsWebBrowserContextMenuEnabled = !state;
}

private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var content = "Custom Content";
if (e.Url.ToString().ToLower() == "about:blank" &&
this.webBrowser1.DocumentText != content)
{
this.webBrowser1.DocumentText = content;
}
}

How to properly display ' and in a WPF WebBrowser that is bound to HTML string

For that you can use a verbatim string and simply escape double quotes with an added double quote.

This sample works for me.

public partial class MainWindow : Window
{
private string html = @"<!DOCTYPE html>
<html lang=""en"">
<body>
<div>My Test HTML 'single quote', ""double quote""</div>
</body>
</html>";
public MainWindow()
{
InitializeComponent();
MyWebBrowser.NavigateToString(html);
}
}

If you are reading the HTML from a file you shouldn't need to do anything special.

MyWebBrowser.NavigateToString(File.ReadAllText(@"C:\myfilepath\myfile.htm"));

generate an HTML-file and display it immediately in a WebBrowser-Control in C#

Try to add the HTML Code to the webbrowser.DocumentText Attribute.

StringBuilder sb = new StringBuilder();
sb.Append("<html><body>");
sb.Append("<a href=");
sb.Append("\"");
sb.Append("http://wwww.microsoft.com");
sb.Append("\"");
sb.Append(">Microsoft</a><p>");
sb.Append("Specify a URL:<br>");
sb.Append("<form method='GET'><input type='text' name='address'/>");
sb.Append("<br><input type='submit'>");
sb.Append("</body></html>");
webBrowser1.DocumentText = sb.ToString();

That's the example from http://msdn.microsoft.com/en-us/library/ms229657%28v=vs.80%29.aspx.

I hope it helps. :-)

How to load HTML string to embedded WebBrowser control?

   Navigate(L"about:blank");

The posted source code does not demonstrate the problem well. It shows no errors, but also no "Hello". Only by omitting the Navigate() call does it get close to failing on nullptr errors. The code is simply not finished, it is missing the required plumbing to capture the DocumentComplete event. Only after this event is fired can the code inside WebBrowser::setHtml() work.

Have the WebBrowser class implement the IDispatch and IUnknown interfaces:

class WebBrowser :
public IDispatch,
public IUnknown,
public IOleClientSite,
public IOleInPlaceSite,
public IStorage
{
private:
HRESULT OnCompleted(DISPPARAMS* args);
wchar_t* htmlSource;
IConnectionPoint* callback;
DWORD eventCookie;
// etc...
};

Note how the htmlSource variable is now a class member, the string needs to be stored until the DocumentComplete event fires.

We need to implement IDispatch. That's pretty easy to do, I put the code inline:

// ---------- IDispatch ----------
HRESULT GetTypeInfoCount(UINT *pctinfo) { return E_FAIL; }
HRESULT GetTypeInfo(UINT, LCID, ITypeInfo **) { return E_FAIL; }
HRESULT GetIDsOfNames(REFIID riid, LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) { return E_FAIL; }

HRESULT Invoke(DISPID dispIdMember, REFIID, LCID, WORD,
DISPPARAMS *pDispParams, VARIANT *pVarResult,
EXCEPINFO*, UINT*) {
if (dispIdMember == DISPID_DOCUMENTCOMPLETE) return OnCompleted(pDispParams);
else return S_OK;
}

QueryInterface() needs to be tweaked:

HRESULT STDMETHODCALLTYPE WebBrowser::QueryInterface(REFIID riid, void**ppvObject)
{
if (riid == __uuidof(IUnknown)) *ppvObject = static_cast<IUnknown*>(this);
else if (riid == __uuidof(IDispatch)) *ppvObject = static_cast<IDispatch*>(this);
else if (riid == __uuidof(IOleClientSite)) *ppvObject = static_cast<IOleClientSite*>(this);
else if (riid == __uuidof(IOleInPlaceSite)) *ppvObject = static_cast<IOleInPlaceSite*>(this);
else
return E_NOINTERFACE;
AddRef();
return S_OK;
}

The constructor needs to subscribe the event interface:

WebBrowser::WebBrowser(HWND _hWndParent)
{
//...
// appended:
htmlSource = nullptr;
IConnectionPointContainer* container = nullptr;
webBrowser2->QueryInterface(IID_IConnectionPointContainer, (void**)&container);
container->FindConnectionPoint(__uuidof(DWebBrowserEvents2), &callback);
IUnknown* punk = nullptr;
this->QueryInterface(IID_IUnknown, (void**)&punk);
callback->Advise(punk, &eventCookie);
punk->Release();
container->Release();
}

The setText() function becomes very simple, we're not going to worry about setHtml() at all. We'll just set the htmlSource member so we know what to do when the DocumentComplete event fires:

void WebBrowser::SetText(const wchar_t* t)
{
const wchar_t* html = L"<html><head><meta http-equiv='x-ua-compatible' content='IE=edge'></head><body><code>%ls</code></body></html>";
if (htmlSource) delete[] htmlSource;
htmlSource = tkString::Format(html, t);
this->Navigate(L"about::blank");
}

And finally the added function that runs when the DocumentComplete event fires. Most of the code got moved from setHtml:

HRESULT WebBrowser::OnCompleted(DISPPARAMS* args) {
HRESULT hr;

IDispatch *pDispatch = 0;
IHTMLDocument2 *pHtmlDoc2 = 0;
IPersistStreamInit *pPSI = 0;
IStream *pStream = 0;
HGLOBAL hHTMLContent;

if (!htmlSource) return S_OK;
hr = webBrowser2->get_Document(&pDispatch);
if (SUCCEEDED(hr) && pDispatch) hr = pDispatch->QueryInterface(IID_IHTMLDocument2, (void **)&pHtmlDoc2);
if (SUCCEEDED(hr) && pHtmlDoc2) hr = pHtmlDoc2->QueryInterface(IID_IPersistStreamInit, (void **)&pPSI);

// allocate global memory to copy the HTML content to
hHTMLContent = ::GlobalAlloc(GMEM_MOVEABLE, (::wcslen(htmlSource) + 1) * sizeof(TCHAR));
if (hHTMLContent)
{
wchar_t * p_content(static_cast<wchar_t *>(GlobalLock(hHTMLContent)));
::wcscpy(p_content, htmlSource);
GlobalUnlock(hHTMLContent);

// create a stream object based on the HTML content
if (SUCCEEDED(hr) && pPSI) hr = ::CreateStreamOnHGlobal(hHTMLContent, TRUE, &pStream);

if (SUCCEEDED(hr) && pStream) hr = pPSI->InitNew();
if (SUCCEEDED(hr)) hr = pPSI->Load(pStream);
}
if (pStream) pStream->Release();
if (pPSI) pPSI->Release();
if (pHtmlDoc2) pHtmlDoc2->Release();
if (pDispatch) pDispatch->Release();
delete[] htmlSource;
htmlSource = nullptr;
return S_OK;
}

I'll leave proper cleanup as a // todo. Running this code now produces the desired outcome:

Sample Image

How to save-as html file, an embeded browser display?

Thanks to Jimi and the following two posts:https://weblog.west-wind.com/posts/2011/may/21/web-browser-control-specifying-the-ie-version. Save WebBrowser Control Content to HTML I have a very nice solution. It is necessary to Imports System.IO and Imports System.Text. Here is the code:

Private Sub BtHTML_Click(sender As Object, e As EventArgs) Handles BtHTML.Click
Dim htmlFile As String = "C:\users\name\fileName"
File.WriteAllText(htmlFile, WebBrowser1.Document.Body.Parent.OuterHtml, Encoding.GetEncoding(WebBrowser1.Document.Encoding))
End Sub


Related Topics



Leave a reply



Submit