I am trying to display HTML files (containing local images) in a WebBrowser control. User can select the file using an OpenFileDialog, after which it is displayed in the control.
But I have these problems I am struggling to solve:
Since I've added the control to my Form, it's been loading really slowly. It takes almost 10s for the form to instantiate.
WebBrowser.Navigate only works the first time. When I try to load the second file, nothing happens. I have tried calling Refresh, Update, OpenNew, opening about:blank between two files, but I just don't have a clue how to do it properly. Only the initially opened file remains shown, no exceptions or warnings ever pop up when I try to navigate to a different page.
Am I doing something wrong? For example, Lutz Roeder's Writer starts instantly and loads subsequent files without problems, but it uses lots of interop (and is editable), so I am trying to avoid all that stuff.
The way I have been loading local .html files into a WebBrowser is like so:
OpenFileDialog ofd = new OpenFileDialog();
// Do filtering here
if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
webBrowser1.DocumentText = System.IO.File.ReadAllText(ofd.FileName);
}
It can load files one after another with no problems. If you are trying to load a big html file when the form is initializing or is opening this could explain the 10 second loading time. My form loaded almost instantly when it had a WebBrowser control on it.
Hope this helps!
Edit: Try setting the stream of the WebBrowser:
System.IO.Stream s = System.IO.File.OpenRead(ofd.FileName);
webBrowser1.DocumentStream = s;
Related
I have a problem in which sometimes (not clear when exactly), displaying an embedded document with docs.google.com does not show the document until I resize the browser window.
Grab some popcorn, here's a movie that shows the problem:
Here's my code:
HTML:
<iframe runat="server" id="frame" style="width:100%;height:600px;border:0;"></iframe>
C# Code begind (in Page_Load method):
frame.Attributes["src"] = "https://docs.google.com/gview?url=https://example.com/1.doc&embedded=true";
I tried reproducing it by browsing directly to https://docs.google.com/gview?url=https://example.com/1.doc&embedded=true but it never happens this way.
Note: Sometimes the document is never displayd at all, as if it was never loaded, and the iFrame remains totaly blank.
Any ideas how to fix this?
You could try to setup a default document size. This is what I do to print envelopes from Google Docs
var envelope10={};
envelope10[DocumentApp.Attribute.PAGE_HEIGHT]=296;
envelope10[DocumentApp.Attribute.PAGE_WIDTH]=684;
envelope10[DocumentApp.Attribute.FONT_FAMILY] = 'Calibri';
envelope10[DocumentApp.Attribute.FONT_SIZE] = 18;
envelope10[DocumentApp.Attribute.BOLD] = true;
envelope10[DocumentApp.Attribute.LINE_SPACING]=1;
This is a problem I've had in the past, but I forgot if I ever solved it or not. I have it so when the user clicks on an asp:linkbutton it triggers a download for a file. File downloads successfully without a problem. However, after it downloads if the user clicks to download again or clicks a button a postback happens and the page refreshes, clearing out everything such as tables or text. How do I prevent this from happening?
Here's the code executing for the download.
string name = Path.GetFileName(filePath);
Response.Clear();
Response.AddHeader("content-disposition", "attachment; filename=\"" + name + "\"");
Response.ContentType = mimeType;
Response.BinaryWrite(file);
Response.End();
NOTES:
The linkbutton control is NOT created behind the scenes in code, if that makes a difference.
The file does not download when clicking the link on the second time. Only a refresh happens.
This is part of a DNN module
First you need to save the information you want to keep before the post back happens. One of the ways this can be done is by using session. For example if you wanted to save the value of a text box you could say:
Session["TextBox1"] = TextBox1.Text;
Then you need to handle the post back in your page load function.
private void Page_Load()
{
//check if this is a post back
if(this.IsPostBack)
{
//restore your values
TextBox1.Text = (string)Session["TextBox1"];
}
}
Okay, I know the source of this problem , but I never found a solution for it. The reason this even shows up is because of a setting in DotNetNuke. Under Host Settings in the Advanced Settings tab if you look at Performance Settings there is a setting called Page State Persistence. If you set this to Memory like I did it will cause AJAX issues. It's even noted in the description. Setting it back to Page makes the problem disappear.
Reason I've kept it as memory is because my company's site was using Memory, however without my knowing it was switched back to Page. Now it's a non issue, but if anyone finds a solution for when it's set to Memory let me know! Otherwise, I'd suggest against using it unless it was fixed in newer versions of DNN.
I have a problem with blocking iframes in the webbrowser control. Currently I am using this code:
foreach (HtmlElement x in ((WebBrowser)sender).Document.GetElementsByTagName("iframe"))
{
MessageBox.Show("iframe!"); //DEBUG
x.OuterHtml = #"<iframe src=""about:blank"" frameborder=""0"" style=""display:none;""></iframe>";
// x.OuterHtml = String.Empty; //gives the same result
}
It works but when navigating to www.popuptest.com , the application just freezes completely because of this code. It shows 2 "iframe!" message boxes and freezes after closing the second one.
I have found the 2 iframes in the source code of webpage (in the advertisements shown on that website). This is the code that is causing it to freeze:
(a=document.createElement("IFRAME"),a.frameBorder=0,a.style.height=0,a.style.width=0,a.style.position="absolute",t=a,document.body&&(document.body.appendChild(a),a=t))&&(a=a.contentWindow)&&(r="1",a.document.open(),a.document.write("<!doctype html><html><head></head><body></body></html>"),a.document.close(),k(a.document))
I guess it is because of the frame being created in a different way? I have tested it both on win7/IE10 and winXP/IE6 and the result is the same. On winXP, however, it crashes and opens the debugger instead of freezing and that is how I got the faulty code.
Is there a better/safer method of removing the content of iframes?
I would try disabling frames using Download Control (DLCTL_NO_FRAMEDOWNLOAD). Here's how it can possibly be done, although I haven't tried that myself. Let us know if that works for blocking frames or not.
I can't seem to find a good way to print .htm files in c# using .net 4.0, visual studio 2010 and windows forms. When i tried to print it directly, it printed the raw html data instead of printing the "page" itself.
The only way i know to print it, is to use a WebBrowser control. When i print the document, it doesn't print colors and the page isn't printed correctly. For example, the edges are not drawn and so on.
Code for Web Browser :
public void Print()
{
// Create a WebBrowser instance.
WebBrowser webBrowserForPrinting = new WebBrowser();
// Add an event handler that prints the document after it loads.
webBrowserForPrinting.DocumentCompleted +=
new WebBrowserDocumentCompletedEventHandler(PrintDocument);
// Set the Url property to load the document.
webBrowserForPrinting.Url = new Uri(Core.textLog);
}
private void PrintDocument(object sender, WebBrowserDocumentCompletedEventArgs e)
{
((WebBrowser)sender).ShowPrintDialog();
//// Print the document now that it is fully loaded.
//((WebBrowser)sender).Print();
//// Dispose the WebBrowser now that the task is complete.
((WebBrowser)sender).Dispose();
}
What can i do?
Thank you!
Printing web pages will forever be the bane of your existence. There just isn't a solution out there that prints HTML directly to your printer really, really well. And even if you do find a program that does it well, it's only a matter of time until you try to print a page with some unsupported formatting, in which case you're right back where you started.
What we do is print HTML to a pdf file with a program called wkhtmltopdf. Then we open it in Acrobat (which has excellent printing support) and print from there. I can't say enough good things about wkhtmltopdf. It's command line driven, and its super, super fast. Best of all, its free. It has a companion program called wkhtmltoimage that will print to most popular image formats, too (bmp, jpg, png, etc).
After downloading/installing the program, you can run a quick test by going to your command prompt, navigating to the install folder, and typing:
wkhtmltopdf "http://YouWebAddress.com" "C:/YourSaveLocation.pdf"
It also has a ton of command line switches that give you greater control over the outputs (headers, footers, page numbering, etc etc).
Ok, as i said, problem was that edge are not drawn and neither are the backgrounds.
Here is how i solved it.
Hashtable values = new Hashtable();
values.Add("margin_left", "0.1");
values.Add("margin_right", "0.1");
values.Add("margin_top", "0.1");
values.Add("margin_bottom", "0.1");
values.Add("Print_Background", "yes");
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Internet Explorer\PageSetup", true))
{
if (key == null) return;
foreach (DictionaryEntry item in values)
{
string value = (string)key.GetValue(item.Key.ToString());
if (value != item.Value.ToString())
{
key.SetValue(item.Key.ToString(), item.Value);
}
}
}
So before i print, i go to regedit, change the values, and the document gets printed perfectly. Hope this helps other people that have the same problem when printing from webbrowser control in windows forms.
There is many similar questions but there is still no clear answer that is solving the problem taking some action after writing some stream to response.
I have a following situation:
On button click I am generating some excel file that I am going to write to response allowing user to download generated file. Imidietly after clicking the button, I am disabling it, to prevent double clicking this button. In Page-Load event handler I have following code:
GenerateBTN.Attributes.Add("onclick", "this.disabled=true;" + ClientScript.GetPostBackEventReference(GenerateBTN, "").ToString());
After Page_Load eventhandler, GenerateBTN_Click handler executes the code needed for generating the file and at the end of this method (handler) I am response writing generated file with following code:
Response.Clear();
Response.ContentType = "application/octet-stream";
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
Response.WriteFile(#"C:\Reports\" + filename);
Response.End();
The Save As dialog appears and user can download the generated file, but the problem is that the disabled GenerateBTN remains disabled. How to enable it afer Writing generated file to response? I understand that afer clearing current response I can not continue with the initial Response, but is there any way to solve this problem?
You can put an IFrame on the page and set it's visiblity to hidden. Have your button load the file in the IFrame and use Javascript to detect if the IFrame is still loading or not. When the loading is done, enable your button.
Can't supply a code example at the moment, but if you decide to go this route and need a sample, let me know I will update this answer.
Edit for 2nd answer
What you want to do is create a file like "Download.aspx" that you pass in the file name as a querystring parameter. This way, you can have your server get the file from a location outside of the Web Application's path and adjust the header to force a file download.
Download.aspx
using System.IO;
protected void Page_Load(object sender, EventArgs e)
{
string FileName = Server.UrlDecode(Request.Params["FileName"]); //Example: "MyFile.txt"
Response.AppendHeader("Content-Type", "application/force-download");
Response.AppendHeader("Content-Disposition", "attachment; filename=" + FileName);
Response.WriteFile(#"C:\MyFolder\" + FileName);
}
You would load the page by calling something like "Download.aspx?FileName=MyFile.txt"
You will need to add checks to make sure the file exists and the querystring parameter exists, but that should force the download and allow you to get the file from another location. When you use an ASPX page to serve the file, you can also do credential checks to see if the user is logged into your site (if you have login logic already) or log the download to a log file/database if you want to keep track of it. It gives you a lot more control over the download process.
As for the IFrame loading code, I'm not 100% sure how this works with a file download, but what I was originally thinking was something like this -- view source on: http://sykari.net/stuff/iframe.
Wrap the button in an UpdatePanel, then simply toggle its enabled property before and after the file work.
You can put an IFrame on the page and
set it's visiblity to hidden. Have
your button load the file in the
IFrame and use Javascript to detect if
the IFrame is still loading or not.
When the loading is done, enable your
button.
Can't supply a code example at the
moment, but if you decide to go this
route and need a sample, let me know I
will update this answer.
I've decided to use your suggestion.. but i still have some questions regarding this problem...
Is it possible to load .txt files in iframe?
Is it possible to load some files that are not included in web application's folder?
The problem with loading txt files in iframe is it does not trigger save as dialog to appear, instead of that file content is displayed inside that iframe.
For loading files into an iframe I've used following code:
HiddenFrame.Attributes["src"] = /GeneratedFiles/ + "test.zip";
You can see that I've had to use relative path and my file has to be included in web app's virtual folder.
What is the best javascript (jquery) eventhandler (function) to detect when Iframe has finished loading? I've used jquery function:
$("#ctl00_ContentPlaceHolder1_HiddenFrame").ready(function () {
if ($("#ctl00_ContentPlaceHolder1_HiddenFrame").attr('src') != '') {
$('#ctl00_ContentPlaceHolder1_GenerateSapFilesBTN').removeAttr("disabled");
}
});
But it appears that button is being enabled before Save As dialog actually appears.. Is it possible to solve this problem with this type of eventHandler or do I have to use some other function...