I have this peculiar problem while wanting to print a html-report. The file itself is a normal local html file, located on my hard drive.
To do this, I have tried the following:
public static void PrintReport(string path)
{
WebBrowser wb = new WebBrowser();
wb.Navigate(path);
wb.ShowPrintDialog()
}
And I have this form with a button with the click event:
private void button1_Click(object sender, EventArgs e)
{
string path = #"D:\MyReport.html";
PrintReport(path);
}
This does absolutely nothing. Which is kind of strange... but things get stranger...
When editing the print function to do the following:
public static void PrintReport(string path)
{
WebBrowser wb = new WebBrowser();
wb.Navigate(path);
MessageBox.Show("TEST");
wb.ShowPrintDialog()
}
It works. Yes, only adding a MessageBox. The MessageBox is showing and after it comes the print dialog. I have also tried with Thread.Sleep(1000) instead, which doesn't work. Can anyone explain to me what's going on here? Why would a messagebox make any difference?
Can it be some kind of permission problem? I've reproduced this on both Windows 7 and 8, same thing. I made this small application with only the above code to isolate the problem. I am quite sure it works on windows XP though, since an older version of the application I'm working on runs on it. When trying to do this directly with the mshtml-dll instead I also get problems.
Any input or clarification is greatly appreciated!
The problem is that the browser is not ready to print yet. You will want to add an event handler WebBrowserDocumentCompletedEventHandler to the WebBrowser Object. Sample code below.
public static void PrintReport(string path)
{
WebBrowser wb = new WebBrowser();
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
wb.Navigate(path);
}
public static void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser wb = (WebBrowser)sender;
if (wb.ReadyState.Equals(WebBrowserReadyState.Complete))
wb.ShowPrintDialog();
}
Related
I'm trying to use function from winform Project to my WPF Project, but the code seems not work with WPF or the structure of WPF. After many hours research I figured out that this code only work for winfowm. I really need to use it to print to thermal printer and I'm using to print html because my printer in this case will print Arabic characters.
Here is the code:
private void button2_Click(object sender, EventArgs e)
{
StartBrowser(xx);
}
public static void StartBrowser(string source)
{
var th = new Thread(() =>
{
var webBrowser = new WebBrowser();
webBrowser.ScrollBarsEnabled = false;
webBrowser.IsWebBrowserContextMenuEnabled = true;
webBrowser.AllowNavigation = true;
webBrowser.DocumentCompleted += webBrowser_DocumentCompleted1;
webBrowser.DocumentText = source;
Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
static void webBrowser_DocumentCompleted1(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var webBrowser = (WebBrowser)sender;
webBrowser.SetBounds(0, 0, 0, 0);
webBrowser.Print();
}
Is there any other way to print HTML like this using WPF?
You could do something similar using WebView2. However, this method doesn't replicate the current behaviour exactly. The WebView2 control needs to be added to the UI before it will be fully initialized.
Follow the steps in Get started with WebView2 in WPF apps:
Make sure you have the WebView2 runtime installed
Add the WebView2 control to your window/page/control:
<DockPanel>
<DockPanel DockPanel.Dock="Top">
<Button x:Name="PopulateWebView2"
Click="PopulateWebView2_Click"
Content="Print"/>
</DockPanel>
<wv2:WebView2 Name="webView2" />
</DockPanel>
Initialize WebView2, and call this in the window/page constructor:
void InitializeAsync()
{
webView2.EnsureCoreWebView2Async(null);
}
Handle the button click and print the page.
private void PopulateWebView2_Click(object sender, RoutedEventArgs e)
{
webView2.NavigateToString(xx); // your html string to populate the browser
webView2.NavigationCompleted += async (s, e) =>
{
await webView2.CoreWebView2.PrintToPdfAsync(#"Path/To/file.pdf");
};
}
As mentioned, the WebView2 control needs to be rendered on the UI before it can be fully initialized. This will print the page as a PDF file to the path specified in PrintToPdfAsync(path).
You could use the built-in print dialog and use the DOM to execute a print command instead using the following command, however that will require input from the user to select the file location:
await webView2.CoreWebView2.ExecuteScriptAsync("window.print();")
It will work as written in WPF, as well as it does in WinForms anyway...
First, add a reference to the System.Windows.Forms assembly.
Then qualify everything...
using WinForms = System.Windows.Forms;
public static void StartBrowser(string source)
{
var th = new Thread(() =>
{
var webBrowser = new WinForms.WebBrowser();
webBrowser.ScrollBarsEnabled = false;
webBrowser.IsWebBrowserContextMenuEnabled = true;
webBrowser.AllowNavigation = true;
webBrowser.DocumentCompleted += webBrowser_DocumentCompleted1;
webBrowser.DocumentText = source;
WinForms.Application.Run();
});
th.SetApartmentState(ApartmentState.STA);
th.Start();
}
static void webBrowser_DocumentCompleted1(object sender, WinForms.WebBrowserDocumentCompletedEventArgs e)
{
var webBrowser = (WinForms.WebBrowser)sender;
webBrowser.SetBounds(0, 0, 0, 0);
webBrowser.Print();
}
I'm writing a software that gets the content from URL. When working on that, I run into to problem that I can not get exactly the HTML content after the java script finished.
There are some websites that renders HTML by java-script, some do not support browsers which does not run js.
I tried using System.Windows.Controls.WebBrowser with WebBrowser.Document in LoadCompleted but no luck.
After that, I tried the OpenWebkitSharp library. On the UI, it showes the content of website correctly, but with code Document in DocumentCompleted, it still returns the content which does not rendered by java-script.
Here is my code:
...
using WebKit;
using WebKit.Interop;
public MainWindow()
{
windowFormHost = new System.Windows.Forms.Integration.WindowsFormsHost();
webBrowser = new WebKit.WebKitBrowser();
webBrowser.AllowDownloads = false;
windowFormHost.Child = webBrowser;
grdBrowserHost.Children.Add(windowFormHost);
webBrowser.Load += WebBrowser_Load;
}
private void WebBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
var contentHtml = ((WebKitBrowser)sender).DocumentAsHTMLDocument;
}
The contentHtml has value which is not rendered after java-script finished.
Do solve this problem, I have added some trick into my code to get the full Html content after java-script finished.
using WebKit;
using WebKit.Interop;
using WebKit.JSCore; //We need add refrence JSCore which following with Webkit package.
public MainWindow()
{
InitializeComponent();
InitBrowser();
}
private void InitBrowser()
{
windowFormHost = new System.Windows.Forms.Integration.WindowsFormsHost();
webBrowser = new WebKit.WebKitBrowser();
webBrowser.AllowDownloads = false;
windowFormHost.Child = webBrowser;
grdBrowserHost.Children.Add(windowFormHost);
webBrowser.Load += WebBrowser_Load;
}
private void WebBrowser_Load(object sender, EventArgs e)
{
//The ResourceIntercepter will throws exception if webBrowser have not finished loading its components
//We can not use DocumentCompleted to load the Htmlcontent. Because that event will be fired before Java-script is finised
webBrowser.ResourceIntercepter.ResourceFinishedLoadingEvent += new ResourceFinishedLoadingHandler(ResourceIntercepter_ResourceFinishedLoadingEvent);
}
private void ResourceIntercepter_ResourceFinishedLoadingEvent(object sender, WebKitResourcesEventArgs e)
{
//The WebBrowser.Document still show the html without java-script.
//The trict is call Javascript (I used Jquery) to get the content of HTML
JSValue documentContent = null;
var readyState = webBrowser.GetScriptManager.EvaluateScript("document.readyState");
if (readyState != null && readyState.ToString().Equals("complete"))
{
documentContent = webBrowser.GetScriptManager.EvaluateScript("$('html').html();");
var contentHtml = documentContent.ToString();
}
}
Hope this one can help you.
I am trying to automate fill the textbox of a website in c# and i used:
private void button1_Click(object sender, EventArgs e)
{
System.Windows.Forms.WebBrowser webBrowser = new WebBrowser();
HtmlDocument document = null;
document=webBrowser.Document;
System.Diagnostics.Process.Start("http://www.google.co.in");
document.GetElementById("lst-ib").SetAttribute("value", "ss");
}
The webpage is opening but the text box is not filled with the specified value. I have also tried innertext instead of setAttribute. I am using windows forms.
You are expecting that your webBrowser will load the page at specified address, but actually your code will start default browser (pointing at "http://www.google.co.in"), while webBrowser.Document will remain null.
try to replace the Process.Start with
webBrowser.Navigate(yourUrl);
Eliminate the Process.Start() statement (as suggested by Gian Paolo) because it starts a WebBrowser as an external process.
The problem with your code is that you want to manipulate the value of your element too fast. Wait for the website to be loaded completely:
private void button1_Click(object sender, EventArgs e)
{
System.Windows.Forms.WebBrowser webBrowser = new WebBrowser();
webBrowser.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser_DocumentCompleted);
webBrowser.Navigate("http://www.google.co.in");
}
private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
webBrowser.document.GetElementById("lst-ib").SetAttribute("value", "ss");
}
Please note that using a instance of a WebBrowser is not often the best solution for a problem. It uses a lot of RAM and has some overhead you could avoid.
I'm using the .NET WebBrowser control in a WinForms application to implement a very basic e-mail template editor.
I've set it in edit mode by this code:
wbEmailText.Navigate( "about:blank" );
( (HTMLDocument)wbEmailText.Document.DomDocument ).designMode = "On";
So the user can modify the WebBrowser content.
Now I need to detect when the user modifies the content 'cause I have to validate it.
I've tried to use some WebBrowser's events like DocumentCompleted, Navigated, etc. but no-one of these worked.
Could someone give me advice, please?
Thanks in advance!
I did have some working, really world code but that project is about 5 years old and I've since left the company. I've trawled my back-ups but can't find it so I am trying to work from memory and give you some pointers.
There are lots of events you can catch and then hook into to find out whether a change has been made. A list of the events can be found here: http://msdn.microsoft.com/en-us/library/ms535862(v=vs.85).aspx
What we did was catch key events (they're typing) and click events (they've moved focus or dragged / dropped etc) and handled that.
Some example code, note a few bits are pseudo code because I couldn't remember off the top of my head the actual code.
// Pseudo code
private string _content = string.empty;
private void frmMain_Load(object sender, EventArgs e)
{
// This tells the browser that any javascript requests that call "window.external..." to use this form, useful if you want to hook up events so the browser can notify us of things via JavaScript
webBrowser1.ObjectForScripting = this;
webBrowser1.Url = new Uri("yourUrlHere");
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
// Store original content
_content = webBrowser1.Content; // Pseudo code
webBrowser1.Document.Click += new HtmlElementEventHandler(Document_Click);
webBrowser1.Document.PreviewKeyDown +=new PreviewKeyDownEventHandler(Document_PreviewKeyDown);
}
protected void Document_Click(object sender, EventArgs e)
{
DocumentChanged();
}
protected void Document_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
DocumentChanged();
}
private void DocumentChanged()
{
// Compare old content with new content
if (_content == webBrowser1.Content) // Pseudo code
{
// No changes made...
return;
}
// Add code to handle the change
// ...
// Store current content so can compare on next event etc
_content = webBrowser1.Content; // Pseudo code
}
I'm trying to make my own webbrowser with C#,
my wpf application seems to be correct. but it's still missing something.
the webpage doesn't appear. :s
Does someone have an idea?
Here's my code in C# :
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void textBox1_TextChanged(object sender, TextChangedEventArgs e)
{
}
private void button1_Click(object sender, RoutedEventArgs e)
{
WebBrowser web = new WebBrowser();
web.NavigateToString (textBox1.Text);
}
Thanks for your help.
As I understand, you are instantiating a new WebBrowser control in code and you aren't adding it as a control to the actual form. You'd better add the control in design view and just do the method call in the code.
When you create the WebBrowser, try adding a third line:
WebBrowser web = new WebBrowser();
Content = web; // extra line
web.NavigateToString (textBox1.Text);
If the textbox is your address bar, it won't work. NavigateToString will interpret what's in your textbox as literal HTML.
web.NavigateToString (textBox1.Text);
should be
web.Source = new Uri(textBox1.Text, UriKind.Absolute);