PROBLEM:
I have a WebBrowser and have exposed its ActiveX methods. In my Form in which the WebBrowser is positioned I have a MainMenuStrip with shortcuts. Only when I am typing in a textbox on my Form do the shortcuts properly work. For example, when I press CTRL + N, a shortcut of my Form - instead of a new Form opening, the page the WebBrowser is currently on opens in IE.
WHAT I'VE TRIED:
I have tried focusing the form every 100ms using a timer which didn't work (this would not be a viable option anyway as it is not very subtle and the program has to carefully navigate the WebBrowser using SendKeys etc).
Code for WebBrowser:
this.webBrowser1.WebBrowserShortcutsEnabled = false;
this.webBrowser1.AllowWebBrowserDrop = false;
this.webBrowser1.IsWebBrowserContextMenuEnabled = false;
Inheriting from WebBrowser and overriding ProcessCmdKey:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.N))
{
newToolStripMenuItem.PerformClick();
return true; // or false
}
}
WHAT I'M TRYING TO ACHIEVE:
That the WebBrowser's shortcuts are disabled (I read somewhere that the ActiveX prevents this...why?).
What I would like is that unless one is currently typing/navigating in the WebBrowser the Form's shortcuts work. Focus should be taken from the WebBrowser WHEREEVER there's a click outside the control, not just when other textboxes are in focus (e.g. when there's a click in the blank of the form.
Try inheriting from WebBrowser control and override Control.IsInputKey. See if Ctrl+N arrives in there.
After investigating a lot, we came to know it is browser compatibility issue.
We have added meta tag into the HTML page,then shortcuts are working fine. Below is the sample code.
<html>
<body>
<Head>
<meta http-equiv="X-UA-Compatible" content="IE=IE8" />
</head>
<form>
First name:<br>
<input type="text" name="firstname">
<br>
Last name:<br>
<input type="text" name="lastname">
</form></body>
</html>
There are three different solutions for this problem.
Adding meta tag to make the Web site browser compatible.
Override "PreocessCmdKey" method and handle the shortcuts.
Emulate browser by adding the key under FEATURE_BROWSER_EMULATION.
If you don't want to set the meta tag in html code, you can assign meta tag to the Document text property of webbrowser control before navigating the URL. Below is the sample.
//Setting compatible mode of IE.
this.m_oWebBrowser.DocumentText = #"<html>
<head><meta http-equiv=""X-UA-Compatible"" content=""IE=IE8"" /> </head>
<body></body>
</html>";
this.m_oWebBrowser.Navigate("www.google.com");
Related
I'm using the old WebBrowser control in a winforms app (C#) to display some static html document. So far, I managed to display what I want, react in a custom way to link clicks, show custom rich tooltips etc.
I'm struggling to set custom mouse cursors, though. The Control itself does not support the ctrl.Cursor property, and setting cursors via CSS in the HTML does only work for standard cursors, NOT for custom cursors.
I'm aware of the neccessity to set the engine to latest (see meta tag in head). The question is, how can I point to a .cur / .png file; I tried with relative paths, absolute paths (just for tests), or doesn't the WebBrowser control maybe allow custom cursors at all?
Here's my snippet:
this.webBrowser1.DocumentText = #"<!DOCTYPE html>
<html>
<head>
<meta http-equiv=""X-UA-Compatible"" content=""IE=edge"" />
<title>Foo</title>
<style>
.customcursor {cursor:url('C:\path\to\stuff.cur'), auto !important;}
</style>
</head>
<body>
<a href='...' class='customcursor'>Foo</a>
</body>
</html>";
I have a Windows Forms application that uses a WebBrowser control to display an embedded web page. The file is (successfully) loaded using:
webHelp.DocumentStream=
Assembly.GetExecutingAssembly()
.GetManifestResourceStream("MyAssembly.help.html");
In order for this to work (i.e. the file to be loaded/displayed) I set the webHelp.AllowNavigation = false;. I don't fully understand why, but if it's set to true, the page is not displayed.
In my HTML document (see bellow) I want to be able to navigate trough different sections. But when I click on a link, the browser control does not go to the targeted element. The web page works fine in the stand-alone Internet Explorer 10, so it must have something to do with the control, more specifically the AllowNavigation property. MSDN didn't help much.
How can I achieve this navigation behavior? Is there another way of loading the HTML file without setting the AllowNavigation property to false?
This is my simple HTML file:
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title>Using this tool</title>
</head>
<body>
<h3>Description</h3>
<div><p id="contents">Contents</p></div>
<div>
<p id="general">Using the file converter</p>
<p>*converter description*</p>
Go To Top!
</div>
<div class="divBlock" >
<p id="selectOption">Selecting a conversion action</p>
<p>*action selection*</p>
Go To Top!
</div>
</body>
</html>
EDIT: After additional tests I found the root of the problem. The problem appeared after setting a value for the URL property, running the application and afterwards clearing this value. The embedded page is not loaded any more, unless the AllowNavigation property is set to false. There are two solutions, described in my answer bellow.
I also have my own WebBrowser. I've tested it and it loads your HTML file perfectly.
I simply used:
webBrowser1.Navigate("C:\\myPath\\SofNavigate.html");
When I click on links it goes to "#contents" without problems.
I am not sure why you need to use webHelp.Docstream instead of simple Navigate.
By the way, when I turn off navivation, then I am not able to go anywhere from the page that I started on. So Navigation must be on in order to go anywhere from the "home page".
Try to debug that part, as it appears to be the bigger problem that you have.
Here is a good example on how to set up simple webBrowser. Try to use it as a base and see what you do differently that messes up your navigation.
[EDITED] Win8/IE10, your code works for me unmodified inside Form.Load event on a simple form which has just a single WebBrowser control with all default settings (and WebBrowser.AllowNavigation is true by default). Check the properties of your WebBrowser control in the Designer, you may have something wrong in there.
[/EDITED]
You're using HTML5, which handles anchor links via id attribute (i.e. <p id="contents"> ... <a href="#contents">. By default, WebBrowser control works in legacy IE7 mode with HTML5 disabled. You need to turn it on with FEATURE_BROWSER_EMULATION feature control, before WebBrowser object gets created. The best place to do this is a static constructor of your form:
static MainForm()
{
SetBrowserFeatureControl();
}
private static void SetBrowserFeatureControl()
{
// http://msdn.microsoft.com/en-us/library/ee330730(v=vs.85).aspx#browser_emulation
// FeatureControl settings are per-process
var fileName = System.IO.Path.GetFileName(Process.GetCurrentProcess().MainModule.FileName);
// make sure the control is not running inside Visual Studio Designer
if (String.Compare(fileName, "devenv.exe", true) == 0 || String.Compare(fileName, "XDesProc.exe", true) == 0)
return;
// web pages containing standards-based !DOCTYPE directives are displayed in Standards mode
using (var key = Registry.CurrentUser.CreateSubKey(
#"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION",
RegistryKeyPermissionCheck.ReadWriteSubTree))
{
key.SetValue(fileName, (UInt32)9000, RegistryValueKind.DWord);
}
}
Try it and your links should work as expected. This solution does NOT require admin rights, the affected key is under HKEY_CURRENT_USER.
[UPDATE] There may be a better solution, it works at least for IE10 here on my side. Add <meta http-equiv="X-UA-Compatible" content="IE=edge" /> as below and leave the registry intact. If you see document.compatMode: CSS1Compat, document.documentMode: 10, you should be good to go, but test with older IE versions too.
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title></title>
<script type="text/javascript">
window.onload = function () {
info.firstChild.data =
"document.compatMode: " + document.compatMode +
", document.documentMode: " + document.documentMode;
}
</script>
</head>
<body>
<pre id="info"> </pre>
</body>
</html>
EDIT: After finding the cause of the problem (see the edit to the question) I can now propose three solutions:
1. WebBrowser control replacement:
Simply delete the existing WebBrowser control and add a new one. This solution does not require any modification of the AllowNavigation property. DO NOT modify the URL property.
2. When deleting and adding a new WebBrowser control is not an option:
Since the AllowNavigation property was influencing the loading and displaying of the web page, there was no reason for it to be left to false afterwards. Setting back the property in the Shown event solved the navigation problem, without requiring other alterations (e.g. in the HTML file or the Registry):
private void helpForm_Shown(object sender, EventArgs e)
{
webHelp.AllowNavigation = true;
}
3. Reseting the Document
It seams that the Document property gets (automatically) initialized if URL property is at one time set and reset. Adding webHelp.Document.OpenNew(true); before loading the resource stream solves the problem without the need for re-adding the WebBrowser and without modifying the AllowNavigation property.
I want to pop up a panel when a "createbutton" is clicked, I am using a panel and adding some textbox and buttons inside the panel. I am able to make the pop up panel by designing it in the same page where the createbutton is present. can I make the pop up in a separate page and make it pop up when I click the createbutton
Gokul,
Yes, you can put the panel in a separate page and make it appear when you click the create button. Here's one alternative (not my favorite but it doesn't depend on anything extra besides standard javascript):
When you click the "create button" open a new browser window resized exactly to match the panel's size. This can be done with javascript easily as follows:
<
input onclick="javascript:window.open('page.aspx','title','status=0,toolbar=0,width=350,height=250');"
type="button" value="Create" />
On the page that you popped up containing the panel (pagecontainingPanel.aspx - according to my example), you can have code to close the window once you perform some action. For example, if you have a button that's supposed to save some data to the database and comeback to the parent page, you could do something like:
{
///Perform server side process. If successfully executed close this window.
protected void btnSubmit_Click(object sender, EventArgs e)
if(EverythingOK)
{
StringBuilder cstext2 = new StringBuilder();
cstext2.Append("<script type=\"text/javascript\"> function CloseMe() {");
cstext2.Append("window.close();} </");
cstext2.Append("script>");
cs.RegisterStartupScript(cstype, csname2, cstext2.ToString(), false);
}
}
Sure. You could create an iframe and then set the source as the panel you're creating.
Let's say you have two html pages panel.html and main.html
Your panel.html can simply be
<html>
<body style="background-color:red">
Hi!
</body>
</html>
and your main.html
<html>
<body style="background-color:yellow">
<iframe src="panel.html" style="height:300px;width:300px;border:0px;display:none;" id="myPanel"></iframe>
Show Panel
</body>
</html>
This should show a yellow page with a hyperlink of "Show Panel". When you click on Show Panel, it will show the iframe of your panel.html.
If you're using ASP.NET MVC, you can do this by creating a View that can be called down with some Ajax/JQuery code. If you're looking for something along that approach, I can post some code for that.
I have the need to render some html text (not an html page with <html> and <body> tags and everything, just some <i>'s and <hr />s and stuff) in a C# .NET 4.0 Winforms application. Preferably it would be a Panel-like control that you could just p.HTML = "somehtml" on and it would display HTML. Has anyone had any experience with .NET HTML rendering controls that they could recommend? I found this on codeproject but I'm a little wary of stuff on there.
Why not use the build in WebBrowser control. You can always enclose your html snippet in standard <html/> markup.
string html = "<i> some text </i>";
webbrowser1.DocumentText = string.Format("<html>{0}</html>", html);
You can try this one link
You can use the WebBrowser control in
design mode with a second WebBrowser
control set in view mode.
In order to put the WebBrowser control
in design mode, you can use the
following code.
This code is a super stripped down
version of a WYSIWYG editor for one of
our software products.
Simply create a new form, drop a
WebBrowser control on it, and put this
in the form_load
Me.WebBrowser1.Navigate("about:blank")
Application.DoEvents()
Me.WebBrowser1.Document.OpenNew(False).Write("<html><body><div id=""editable"">Edit this text</div></body></html>")
'turns off document body editing
For Each el As HtmlElement In Me.WebBrowser1.Document.All
el.SetAttribute("unselectable", "on")
el.SetAttribute("contenteditable", "false")
Next
'turns on editable div editing
With Me.WebBrowser1.Document.Body.All("editable")
.SetAttribute("width", Me.Width & "px")
.SetAttribute("height", "100%")
.SetAttribute("contenteditable", "true")
End With
'turns on edit mode
Me.WebBrowser1.ActiveXInstance.Document.DesignMode = "On"
'stops right click->Browse View
Me.WebBrowser1.IsWebBrowserContextMenuEnabled = False
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.