WPF Webbrowser - Access to Document Body on IE11 - c#

I'm developing a Desktop application which stores the GUI layer on html files as embedded resources. And I have a WPF Web Browser that manages the user interface lifecycle. I'm able to do all the job with no problems. But I've recently found out that when enabling the FEATURE_BROWSER_EMULATION to IE 11 (11000), the document body becomes inaccessible. Then, when using IE 10 (10000) everything works nicely.
The example below shows how to get the document body OffsetHeight:
dynamic document = (this.wbContent.Document as dynamic);
if ((document == null) || (document.body == null)) return 0;
return document.body.OffsetHeight;
The HTML is:
<html>
...
<body style="width: 170px; height: 240px">
...
</body>
</html>
When using IE 11 it throws an exception of type 'Microsoft.CSharp.RuntimeBinder.RuntimeBinderException'.
When using IE 10 it returns 240.
Have you got any idea about how to access body on IE 11?

As I did not get any answer about solving the problem, I had to trick in order to work around the bug. What is did is to put a simple JavaScript on the html file, so I call the method window.resizeTo(a, b). After this event is called, the application get back working, but I actually don't know why.

Related

WPF WebBrowser Control will not load video in a locally hosted HTML page

I have a WPF application written in C#. This application has two WPF WebBrowser controls next to each other. Each one navigates to a different locally-hosted HTML file. Each HTML file has a video element which points to an .mp4 video file stored in the same directory.
My problem is that the video content does not render in the WebBrowser controls. If I use the exact same URL and put it into Internet Explorer 11 on the same PC, the video content runs perfectly fine. I know the actual navigations of the WebBrowser controls are working because the page half-renders. I can see the background color show correctly but that is it. If I right-click inside one of the controls and view the source, I can see the correct HTML there.
Attempting to apply the recommendation in an answer to this question to Internet Explorer 11, I tried having the WebBrowser controls in my executable run like IE11 using the information in this link with no success.
I'm not sure if this is relevant, but I already have "Allow active content to run in files on My Computer" checked in Internet Options on Internet Explorer.
Here is the HTML markup for the video:
<div id="video_holder">
<video id="video" width="1200" height="900" autoplay>
<source src=".\FANCY.mp4" type="video/mp4">
</video>
</div>
And here is the code that calls the Navigate() method of the WebBrowser controls (the constructor for this Form receives the urls from another class - I'm pretty sure the problem isn't here, though, as I can see that the actual navigation seems to be working and the HTML starts to render):
public partial class TwoPaneWindow : Window
{
private string leftUrl;
private string rightUrl;
public TwoPaneWindow(string left, string right)
{
leftUrl = left;
rightUrl = right;
}
public void StartWindow()
{
InitializeComponent();
this.Show();
LeftBrowser.Navigate(leftUrl);
RightBrowser.Navigate(rightUrl);
}
}
Can anyone tell what is going on? I am hosting this on IIS installed on Windows 8.1. Thank you in advance for any help you can offer.
Finally figured this out. Even though I said I tried the answer to this question, I was actually using the FEATURE_BROWSER_EMULATION key incorrectly. I attempted to add FEATURE_BROWSER_EMULATION to HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Main\FeatureControl, when in fact it needs to be modified at HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION. Once I created a new DWORD entry for my application (sharing its name) with a value of 0x2AF8, the WebBrowser controls immediately started working correctly. A newbie mistake I'm sure, but hopefully this helps someone else in the future.

C# Setting InnerHtml to "" for an element which is updated by server causes element to stop updating

I have a C# Windows Forms Application with a webBrowser within it. It visits a Wikia chatroom, where it then locates the element which contains the chat output. This element looks like:
<div style="" id="Chat_XXXXX" class="Chat">
<ul>
(chat text)
</ul>
</div>
The purpose of the program is to retrieve the chat text every once in a while for logging purposes. This is easily done by parsing the "InnerHtml" of the "Chat_XXXXX" element. However, I also need to clear the text from the window when I do this (for various reasons, I cannot leave the text in the window). I figured I would just erase the chat text portion of the element, as this is how it is done with a handy javascript file called "chat hacks" for Wiki chat (here). Or at least, I think that's how it does it. If you look at the function "clearWindow" in that file, you can see what it does:
NodeChatController.prototype.clearWindow = function() {
this.viewDiscussion.chatUL.html('');
this.inlineAlert(i18n['cleared']);
}
I have tried setting the InnerHtml of "Chat_XXXXX" using the following three strings (not all at the same time, of course):
HtmlDocument document = webBrowser1.Document;
document.GetElementById("Chat_XXXXX").InnerHtml = ""
document.GetElementById("Chat_XXXXX").InnerHtml = "<ul></ul>"
document.GetElementById("Chat_XXXXX").InnerHtml = "<ul><li class=\"inline-alert\"> Window cleared. </li></ul>"
However, although these clear the window (and in the case of the last one prints a message), the chat no longer updates as new messages show up. The only fix is to reload the page, which isn't an option, because reloading the page brings in a whole load of chat history (which I'm trying to avoid). I've also tried importing that javascript mentioned above into the page using:
HtmlElement head = webBrowser1.Document.GetElementsByTagName("head")[0];
HtmlElement scriptEl = webBrowser1.Document.CreateElement("script");
scriptEl.SetAttribute("type", "text/javascript");
scriptEl.SetAttribute("src", "https://db.tt/66q8UQbY");
head.AppendChild(scriptEl);
This javascript creates a button which clears the chat window. The button clears the window just fine, but again, the chat no longer updates. I know this button works correctly without stopping further incoming chat in "regular" browsers (Chrome, Firefox, Opera, etc). I've used it many times, and the script itself is quite popular in the Wikia community. I've already followed the steps here: "WPF WebBrowser Control - position:fixed Element jumps while scrolling (Windows 8)" to get the browser to act as close as it can (?) to Internet Explorer. I've already checked the Body field of the document after altering the InnerHtml to make sure that my replacements didn't alter anything important. Just for clarity, here's an example of what is contained in the (chat text) portion of my original example:
<li class="you" data-user="UserNameHere" id="entry-c812">
...avatars and junk...
<span class="message">hello</span>
</li>
I honestly have no idea what could be causing the chat element to stop updating after it has been edited (especially since it works outside of this program), so I don't know what information to include. Whatever you need, I'll provide it. Here's the javascript from Wikia which generates the chat output window: chat_js2. Look for "Chat_" to find the part which originally generates the window. I don't know where the output is updated in that file though.

C# WebBrowser won't display embedded object

This may be a dumb question, but I just can't get it to work. I'm trying to embed a pdf file into a webbrower in a c# program. Simple right? I thought so, but it proved otherwise.
Here's the html code:
<object classid="" type="application/pdf" width="400" height="300" id="pdf1">
<param name="src" value="Test.pdf" />
<div style="text-align:center; color:#CCCCCC" >No Preview Available.</div>
</object>
And that's all thats in the html file. The funny thing is, this works perfectly in IE (which as I understand is what the WebBrowser uses). I've tried implementing the object tag the non-IE way, with an src attribute and whatnot, but it did the same thing. What's happening is the WebBrowser control is just displaying No Preview Available meaning that the pdf was not successfully embedded. Here's the c# code:
wbPreview.Navigate("I:/Documents/Visual Studio 2008/Projects
/PlanReferenceDatabase/test.html");
Can someone tell me why the web browser in c# cannot display the pdf, but the other browser can?
Try formatting the tag like this:
<object type="application/pdf" data="myPdfFile.pdf" class="yourPdfClass" width="550px" height="800px"/>
Include the data attribute in the tag and it seems to work just fine - just tried this in my browser control on a IE8 / IE9 machine and it displays inline.
I solved my problem. Just in case anyone else has the same one, here's what I did:
First I set the "target platform" property under the build tab in visual studio to x86 because as it turns out, 64bit IE can't render PDFs.
Second I used the embed tag instead of the object tag, because IE requires you to use "classid" and all sorts of Active X stuff you don't want when you use the object tag.

C#: Open a browser and POST to a url from a windows desktop app

I have a small WPF app (although I guess it doesn't really matter whether it's a wpf form or a webform app?) that I want to have launch a new browser window and POST to a specific url. I've been messing around with:
System.Diagnostics.Process.Start("http://myurl.com");
to launch the window but I don't think I can use the same process to actually post to a url...I've also experimented with HttpWebRequest but I would like the user to be able to use the app after I have posted to this url, not just show them the results...What can I look at to able to do something like this?
There is no direct way to do it. What you could do is generate a HTML page with a form filled with the data you need to post, and a bit of javascript to post the page automatically when it is loaded. Then you just have to open that page in the browser...
The generated HTML could look like that :
<html>
<head>
<script language="Javascript">
function submitForm() {
var theForm = document.getElementById("theForm");
theForm.submit();
}
</script>
</head>
<body onload="submitForm()">
<form id="theForm" action="http://myurl.com" method="POST">
<input type="text" name="username" value="myusername"/>
<input type="password" name="password" value="mypassword"/>
</form>
</body>
</html>
If the page must be displayed in your application, load it in a WebBrowser control
Use the WebBrowser Class instead.
There are multiple solutions, not sure which one would be the best for you...
Proceed with your original approach
Embed web browser control in your applicaiton as suggested in other answers
Do everything programmatically "behind the scene"
For #3 you may want to look here: http://geekswithblogs.net/rakker/archive/2006/04/21/76044.aspx
If you want to go with #1 - it is more tricky, since you need to control external application and different browsers would behave differently.
I've used "javascript:" protocol and the code below with IE as default browser when dealing with one "user-unfriendly" application. Please note that it's not "production-ready" code. There is no error handling, user may shift focus away from launched browser, or use browser without "javascript:" protocol support etc.
static void Main()
{
Settings s = Settings.Default;
Process.Start(s.URL1);
Thread.Sleep(s.Delay1);
SendKeys.SendWait("%D");
Thread.Sleep(100);
SendKeys.SendWait(EncodeForSendKey(s.URL2));
SendKeys.SendWait("{ENTER}");
}
public static string EncodeForSendKey(string value)
{
StringBuilder sb = new StringBuilder(value);
sb.Replace("{", "{{}");
sb.Replace("}", "{}}");
sb.Replace("{{{}}", "{{}");
sb.Replace("[", "{[}");
sb.Replace("]", "{]}");
sb.Replace("(", "{(}");
sb.Replace(")", "{)}");
sb.Replace("+", "{+}");
sb.Replace("^", "{^}");
sb.Replace("%", "{%}");
sb.Replace("~", "{~}");
return sb.ToString();
}
URL1: http://www.google.com
URL2: javascript:function x(){document.all.q.value='stackoverflow';document.forms[0].submit();} x();
You can create a hidden WebBrowser control and do Navigate() (using the overload that allows you to specify the request method). You will need to specify a "_blank" target frame to cause the navigation to happen in a new browser window.

print an asp .net page without considering IE version

I have an ASP.NET site with a print option (onclick = window.print())
the problem is that when using IE 7 it gets fine on the page
but when users using IE 6 print the page they get it larger than the page is
It depends up on the default print settings set on the client machine.
This has nothing to do with ASP.NET.
Also, OnClick = Window.Print() is a JavaScript function which would be executable in the client machine.
You can use the CSS to control the way the page needs to be printed/viewed.
#media print {
BODY { font-size: 10pt }
}
#media screen {
BODY { font-size: 12pt }
}
#media screen, print {
BODY { line-height: 1.2 }
}
You cannot control the printing so you get the same result regardless of client, that's one of the "beauties" of HTML.
IE7 for instance introduced enhanced user-controlled printing options to "fix" some of the problems while printing web sites. This is still in the hands of the user though, and caters for their idea how the page in question would be best printed, and not really something the page itself or web developer can control.
If you need something for controlled print, use a suitable format instead - like PDF (generate it on the fly if needed).

Categories

Resources