I've been searching for a long time whether I could make google chrome to print specific html doc via C# app. Unfortunately I didn't find an answer. So, is there any way to print html docs with GC but not with IE? p.s. Thank for any answer
namespace testPritn
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void PrintHelpPage()
{
// 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(#"D:\test.html");
}
private void PrintDocument(object sender,
WebBrowserDocumentCompletedEventArgs e)
{
// Print the document now that it is fully loaded.
((WebBrowser)sender).Print();
// Dispose the WebBrowser now that the task is complete.
((WebBrowser)sender).Dispose();
}
private void button1_Click(object sender, EventArgs e)
{
PrintHelpPage();
}
}
}
Related
Attached is a screenshot as well as the code. There isn't much of it.
When I first open the window, everything is rendered with an offset.
If I close the window and reopen it, it renders correctly the second time.
public partial class frmTwinklyLogin : Form
{
public ChromiumWebBrowser webBrowser;
public frmTwinklyLogin()
{
InitializeComponent();
InitializeBrowser();
}
private void frmTwinklyLogin_Load(object sender, EventArgs e)
{
}
private void InitializeBrowser()
{
webBrowser = new ChromiumWebBrowser("https://api.twinkly.com/v2/auth/login?response_type=code&client_id=omen-hp-client&redirect_uri=http://localhost:8487/login");
webBrowser.AddressChanged += Browser_AddressChanged;
this.Controls.Add(webBrowser);
webBrowser.Dock = DockStyle.Fill;
webBrowser.Refresh();
}
private void Browser_AddressChanged(object sender, AddressChangedEventArgs e)
{
var x = e.Address;
if (x.Contains("code="))
{
var code = x.Split('=')[1];
TwinklyWebApi.SetCode(code);
}
}
}
and the initialization of the library is in application load.
static void Main()
{
CefSettings settings = new CefSettings();
Cef.Initialize(settings);
I can only assume I've got something in the wrong event. Either that or my monitor dpi is screwing with it. Note: It's merely rendered off-center. The click areas for the controls are still where they are supposed to be, which makes the page unusable.
I want to navigate to the URL rather than it opening a separate instance.
No matter what I do it still opens another instance of WebView2.
private void CoreWebView2_NewWindowRequested(object sender,
CoreWebView2NewWindowRequestedEventArgs e)
{
//e.NewWindow = webView21.CoreWebView2;
e.NewWindow = (CoreWebView2)sender;
//e.Handled = true;
}
here's the original post, what do I need to do for it to handle the new window request?
To receive a notification when a new Popup Windows is requested, subscribe to the the NewWindowRequested of CoreWebView2.
The event is raised when there's a request to generate a Popup. Clicking a link that just cause the Browser to navigate to a different URI doesn't raise the event (no popup).
A new Popup Window can be requested if the User clicks the Open link in new window (sic) option of the standard ContextMenu provided by the Browser.
Or if the Web Page generates one without user intervention.
Unfortunately, the e.IsUserInitiated property is always true, so you may have a hard time determining (without injecting JavaScripts) whether the popup should be blocked (in case you want to, that is).
When a new Window is requested, you can block it indiscriminately setting e.Handled = true
If you want to open the new Window URI to the same Window, you can specify either:
e.Handled = true;
e.NewWindow = (CoreWebView2)sender;
// or
e.Handled = true;
((CoreWebView2)sender).Navigate(e.Uri);
Sample WebView2 main handler Form:
using Microsoft.Web.WebView2.Core;
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
protected override async void OnLoad(EventArgs e)
{
base.OnLoad(e);
webView2.CoreWebView2InitializationCompleted += OnCoreWebView2InitializationCompleted;
var env = await CoreWebView2Environment.CreateAsync(null, null, null);
await webView2.EnsureCoreWebView2Async(env);
webView2.Source = new Uri("https://www.somesite.com");
}
private void OnCoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
webView2.CoreWebView2.NewWindowRequested += OnNewWindowRequested;
}
private void OnNewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e)
{
// Open the Uri requested in the current Window
e.Handled = true;
((CoreWebView2)sender).Navigate(e.Uri);
}
// Or, if you want to handle Popup Windows using your own Form template
// => Note that it's the same event handler as above, pick one, not both!
private void OnNewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e)
{
// Open the Uri requested in a new instance of the PopupWindow Form
var deferral = e.GetDeferral();
e.Handled = true;
var popup = new PopupWindow(deferral, e);
popup.Show();
}
}
If you instead want to create a new Form that will show the popup, you need a Form template (it can be just a Form that contains a WebView2 Control) that receive the CoreWebView2Deferral returned by e.GetDeferral().
In the initialization procedure of this Form check whether the CoreWebView2Deferral object is null. If it's not, complete the deferred event by calling its Complete() method.
Then subscribe to the NewWindowRequested event to perform the same action when a new Popup Window is requested (unless you want to block it).
Of course you can show these Forms inside a Tabbed Control, to generate a standard tabbed view, common in all WebBrowsers.
Sample PopupWindow Form:
using Microsoft.Web.WebView2.Core;
using System.Windows.Forms;
public partial class PopupWindow : Form
{
public PopupWindow() => InitializeComponent();
public PopupWindow(CoreWebView2Deferral deferral, CoreWebView2NewWindowRequestedEventArgs args)
: this() {
Core2Deferral = deferral;
NewWindowArgs = args;
}
protected virtual CoreWebView2Deferral Core2Deferral { get; private set; }
protected virtual CoreWebView2NewWindowRequestedEventArgs NewWindowArgs { get; private set; }
protected async override void OnLoad(EventArgs e)
{
base.OnLoad(e);
webView2.CoreWebView2InitializationCompleted += OnCoreWebView2InitializationCompleted;
var env = await CoreWebView2Environment.CreateAsync(null, null, null);
await webView2.EnsureCoreWebView2Async(env);
}
private void OnCoreWebView2InitializationCompleted(object sender, CoreWebView2InitializationCompletedEventArgs e)
{
webView2.CoreWebView2.Settings.AreDefaultContextMenusEnabled = true;
if (Core2Deferral != null) {
NewWindowArgs.NewWindow = webView2.CoreWebView2;
Core2Deferral.Complete();
}
webView2.CoreWebView2.NewWindowRequested += OnNewWindowRequested;
}
private void OnNewWindowRequested(object sender, CoreWebView2NewWindowRequestedEventArgs e)
{
e.Handled = true;
var popup = new PopupWindow(e.GetDeferral(), e);
popup.Show();
}
}
How about making it works like real web browsers. Simply, opens in an new Tab. Just with a few lines of codes ;)
At first, create a new class which inherits from WebView2 and include a TabControl field inside it:
internal class WebViewInTab:WebView2
{
TabControl tabCtrl;
public WebViewInTab(TabControl tabCtrl) :base()
{
Dock = DockStyle.Fill; // necessary for showing
this.tabCtrl = tabCtrl; // for adding new TabPage controls
CoreWebView2InitializationCompleted += WebViewInTab_CoreWebView2InitializationCompleted;
}
Then, you'll use this custom webview2 to create new webview2 objects every time CoreWebView2.NewWindowRequested event is raised. So to handle the event:
private void WebViewInTab_CoreWebView2InitializationCompleted(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2InitializationCompletedEventArgs e)
{
CoreWebView2.NewWindowRequested += CoreWebView2_NewWindowRequested; // This is the man
CoreWebView2.DocumentTitleChanged += CoreWebView2_DocumentTitleChanged; // Just cosmetic code
}
After that, you'll handle the new window by yourself, i.e. , Just add a new TabPage control with our custom webview2 to the TabControl TabPages collection. Of course, not forgeting the Uri from handler arg.
private void CoreWebView2_NewWindowRequested(object? sender, Microsoft.Web.WebView2.Core.CoreWebView2NewWindowRequestedEventArgs e)
{
e.Handled = true; // let the default new window
TabPage tpage = new TabPage(); // boy
tpage.Controls.Add(new WebViewInTab(tabCtrl) { Source = new Uri(e.Uri)}); // toy
tabCtrl.TabPages.Add(tpage); // daddy
tabCtrl.SelectedTab = tpage; // user expectation
}
//Just cosmetic code
private void CoreWebView2_DocumentTitleChanged(object? sender, object e)
{
int last = tabCtrl.TabPages.Count - 1;
tabCtrl.TabPages[last].Text = CoreWebView2.DocumentTitle
}
}
Finally, :) start the recursion-ready operation in the main app form constructor.
public Form1()
{
InitializeComponent();
string uriAdd = "https://www.w3schools.com/";
tabControl1.TabPages[0].Controls.Add(new WebViewInTab(tabControl1) { Source = new Uri(uriAdd) });
}
I hope you can help me. I try to code a litle browser using cef.
The problem is, I get a access violation while changing the Text of a TextBox at public void browser_FrameLoadEnd
public partial class Internet : Page
{
string Url;
public Internet()
{
InitializeComponent();
}
private void surf_Click(object sender, RoutedEventArgs e)
{
browser.Load(uri.Text);
}
public void browser_FrameLoadEnd(object sender, CefSharp.FrameLoadEndEventArgs e)
{
uri.Text = Url;
}
private void browser_FrameLoadStart(object sender, CefSharp.FrameLoadStartEventArgs e)
{
this.Url = e.Url;
}
}
please help me. Why it will not work ?
I guess that the event arrives in a different thread. Hence you have to call the Invoke method of the TextBox, e.g.
uri.Invoke((MethodInvoker)(() => uri.Text = Url));
Being fairly new to C# and OOP I'm having some newbie problems with scope and access, one of them being this: When the main form loads an instance of the class Doc is created and the constructor opens a Word document and creates a list of all the images in the document. The first image in the list is displayed in a picturebox, like so:
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
public class Doc {
public List<Image> images = new List<Image>();
public Doc(string path) {
// Open Word document, create list of images
}
}
private void Form1_Load(object sender, EventArgs e) {
Doc doc = new Doc("C:\\lorem_ipsum.doc");
pictureBox1.Image = doc.images[0];
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
pictureBox1.Image = doc.images[numericUpDown1.Value];
}
}
There is also a numericUpDown control which should be used to display different images, and that's where the problem is. The last block of code in the example above doesn't work, but I hope it illustrates what I want to do.
What would be a best practice solution to this problem (and similar ones where one control should be able to access objects created by other controls)? I have also tried to solve it by creating a method for the Doc class but had problems accessing the picturebox from there instead.
Your problem is you created doc as a local variable. You need a member variable within the scope of the class:
public partial class Form1 : Form {
private Doc _doc; // Add this line
public Form1() {
InitializeComponent();
}
public class Doc {
public List<Image> images = new List<Image>();
public Doc(string path) {
// Open Word document, create list of images
}
}
private void Form1_Load(object sender, EventArgs e) {
_doc = new Doc("C:\\lorem_ipsum.doc");
pictureBox1.Image = _doc.images[0];
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
pictureBox1.Image = _doc.images[numericUpDown1.Value];
}
}
A little about scope
public class MyClass
{
// myMemberVariable is declared inside class, but outside
// a function. Therefore, it can be accessed from anywhere
// inside the class.
int myMemberVariable;
public void MyFunction()
{
// myLocalVariable is declared inside a function. Therefore,
// it can be accessed only inside this function and nowhere
// else.
int myLocalVariable;
for (int x=0;x<10;x++)
{
// anotherLocalVariable is declared inside a for loop. Therefore,
// this variable can only be used inside this for loop and
// no where else.
int anotherLocalVariable;
}
}
}
Think of the braces as scope delimiters. Variables you create can only be used within the opening and closing braces and never outside. The only "partial" exception to this would be static variables.
Just make doc a private field of Form1.
public partial class Form1 : Form {
private Doc doc;
public Form1() {
InitializeComponent();
}
public class Doc {
public List<Image> images = new List<Image>();
public Doc(string path) {
// Open Word document, create list of images
}
}
private void Form1_Load(object sender, EventArgs e) {
doc = new Doc("C:\\lorem_ipsum.doc");
pictureBox1.Image = dok.images[0];
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e) {
pictureBox1.Image = doc.images[numericUpDown1.Value];
}
}
The doc you have there is a local variable, i.e. it's local to Form1_Load. That means it only exists inside that method. What you want is a member field, defined on the Form1 class itself. That will stick around as long as the form exists:
public partial class Form1 : Form
{
private Doc m_Doc;
....
private void Form1_Load(object sender, EventArgs e)
{
m_Doc = new Doc("C:\\lorem_ipsum.doc");
pictureBox1.Image = m_Doc.images[0];
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
pictureBox1.Image = m_Doc.images[numericUpDown1.Value];
}
}
Now m_Doc will be accessible to anything in the class (and to nested classes as well), but nothing else, since it's private.
I've also chosen to add a m_ suffix. It is not necessary and people will argue about what convention is best all night long, but that's what I prefer!
How can I make the code when run the code it go to example.com
private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
webBrowser1.Navigate("www.example.com");
}
Please correct it when run program it go to example.com
private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
webBrowser1.Navigate("www.example.com");
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (webBrowser1.Document != null)
{
IHTMLDocument2 document = webBrowser1.Document.DomDocument as IHTMLDocument2;
if (document != null)
{
IHTMLSelectionObject currentSelection = document.selection;
IHTMLTxtRange range = currentSelection.createRange() as IHTMLTxtRange;
if (range != null)
{
const String search = "ant";
if (range.findText(search, search.Length, 2))
{
range.select();
}
}
}
}
}
Can you Navigate to example.com at Form.Load event? It's working fine in my machine.
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("www.example.com");
}
You need to handle the Load event of your form (Form1) if you want the WebBrowser control to automatically navigate to www.example.com whenever your form is shown on the screen.
As it's written now, you handle the Navigated event of the WebBrowser control and tell it to navigate somewhere else. However, the Navigated event is only raised when the browser has navigated to and begun loading a new page. Even if you get your code to work, it will be perpetually chasing its own tail.
Instead, try the following:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("http://www.example.com");
}
}
public Form1()
{
InitializeComponent();
webBrowser1.Navigate("http://www.example.com");
}
This execute the navigate method after the app is initialized.
I'm not sure if I understand your question: The e variable in the webBrowser1_DocumentCompleted method contains the Url property that holds the current Uri object with the URL where the browser control has arrived:
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
WebBrowser browser = (WebBrowser)sender;
if (e.Url.Host.EndsWith("example.com"))
{
// do something
}
}