CefBrowser offset render when first loaded - c#

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.

Related

WPF: How to pass data to PAGE from MainWindow in codebehind?

Hi members,
I have a simple question about how to pass data to Page from MainWindow.
I searched on google/ and here... But I am not found exact answer.
I would like modify, change the Page1( SW_GUI.xaml) elements such as label content, or later change other GUI element content.
However I only can reached (myself) this way: firstly make change on label of SW_GUI.xaml and then create instance of this Page(SW_GUI.xaml) and load in a frame of MainWindow content.
But if this Page loaded once, I cannot modify /update a label automatically, without loading the SW_GUI Page again into the frame.
You can find the very simple and initial code below.
MainWindow.xaml.cs file
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// ACTION one - just try reason
SW_GUI sW_GUI = new SW_GUI();
sW_GUI.RESULT_MAKER(true);
CenterFrame.Content = sW_GUI;
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// ACTION two - just try reason
SW_GUI sW_GUI = new SW_GUI();
sW_GUI.RESULT_MAKER(false);
CenterFrame.Navigate(sW_GUI);
}
}
-----------------
PAGE1 aka SW_GUI
SW_GUI.xaml.cs file
public partial class SW_GUI : Page
{
public SW_GUI()
{
InitializeComponent();
}
public void RESULT_MAKER ( bool results)
{
if (results==true)
{
RESULT_BOX.Background = new SolidColorBrush(Color.FromRgb(0, 245, 95));
RESULT_BOX.Text = "(PASS)";
}
else
{
RESULT_BOX.Background = new SolidColorBrush(Color.FromRgb(245, 53, 0));
RESULT_BOX.Text = "(FAIL)";
}
}
}
SHORT logic: Button_Click on mainwin call the sW_GUI.RESULT_MAKER method and make very simple change on a label. Then, I load the sW_GUI instance into the CenterFrame.Content.
QUESTION: Ca you provide a little guide or give a simple example what I have to add, change to achieve that I don't need to load the page into the frame each case when I want to update a label content etc.
Many thanks for it.
Hello I have made a small sample in MainWindow.cs:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private SW_GUI SW_GUIPage = new SW_GUI();
private void ActivateSW_GUI(bool SetResult)
{
SW_GUI SW = SW_GUIPage;
SW.RESULT_MAKER(SetResult);
if (!(CenterFrame.Content is SW_GUI))
{
CenterFrame.Content = SW_GUIPage;
}
}
int ActionSetter = 0;
private void Button_Click(object sender, RoutedEventArgs e)
{
if (ActionSetter == 0)
{
ActivateSW_GUI(true);
ActionSetter = 1;
}
else if (ActionSetter == 1)
{
ActivateSW_GUI(false);
ActionSetter = 0;
}
}
}

e.NewWindow = (CoreWebView2)sender still results in a separate instance

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) });
}

C# silent printing with Google Chrome

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();
}
}
}

How can i close Morden UI page with code?

here on Button click to close mordenwindow..thats doesn't work
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// this MainWindow is like this --> <mui:ModernWindow x:Class="FirstFloor.ModernUI.App.MainWindow1" ....>
MainWindow1 mw = new MainWindow1();
// this is my login Page..
Login lg = new Login();
lg.Show();
mw.Close(); //here code is not working
}
What you did in that Button_Click_1 event is you created a new ModernWindow1 then you closed that newly created ModernWindow1, . Now, you technically have two ModernWindow1 in the start of that event. What you need is to close the currently running ModernWindow1, and not the newly created ModernWindow1. to do that, you need to reference the old ModernWindow1 before going to another window.
This is the Second ModernWindow
public partial class ModernWindow2 : ModernWindow
{
public dynamic ReferencedWindow2; //you will put the original Window here
public ModernWindow2()
{
InitializeComponent();
}
public ModernWindow2(dynamic referencedWindow) // second constructor with a parameter
{
InitializeComponent();
ReferencedWindow2 = referencedWindow; // the original modernwindow being put in here
}
private void Button_OnClick(object sender, RoutedEventArgs e)
{
ReferencedWindow2.Close();
}
}
THIS IS THE ORIGINAL OR PRIMARY MODERNWINDOW
public partial class ModernWindow1 : ModernWindow
{
public ModernWindow1()
{
InitializeComponent();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
/*
this will show the second modernwindow using the second constructor with parameter
*/
ModernWindow2 newWindow2 = new ModernWindow2(this);
newWindow2.Show();
}
}

C# How do I create code to set a form back to default properties, with a button click event?

Using Visual C# 2008 express edition, I am trying to create a button on my form to set the form back to default properties, such as size, backcolor, etc... anybody have any examples on how I would do this?
By far the simplest way is to just create a new instance of the form and close the old one. That requires a little bit of surgery if this is the main form of your app, closing it would terminate the program. Start by opening Program.cs and edit it so it looks like this:
static class Program {
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
AppContext = new ApplicationContext();
AppContext.MainForm = new Form1();
Application.Run(AppContext);
}
public static ApplicationContext AppContext;
}
The ApplicationContext variable now controls the lifetime of the app, instead of the Form1 instance. You can recreate the form with code like this in Form1:
private void button1_Click(object sender, EventArgs e) {
Form1 frm = new Form1();
frm.StartPosition = FormStartPosition.Manual;
frm.Location = this.Location;
frm.Size = this.Size;
Program.AppContext.MainForm = frm;
frm.Show();
this.Close();
}
For each property info you can get DefaultValueAttribute and set needed Property to its value.
You cannot do this without saving the original state somewhere.
Just create some class that holds the default info:
class DefaultFormInfo
{
int Width { get; set; }
int Height { get; set; }
}
Then use some reflection:
static DefaultFormInfo FormInfo = new DefaultFormInfo();
void FillDefaults()
{
foreach (PropertyInfo pinf in FormInfo.GetType().GetProperties())
{
pinf.SetValue(FormInfo, this.GetType().GetProperty(pinf.Name).GetValue(this, null), null);
}
}
void Restore()
{
foreach (PropertyInfo pinf in FormInfo.GetType().GetProperties())
{
this.GetType().GetProperty(pinf.Name).SetValue(this, pinf.GetValue(FormInfo, null), null);
}
}
The simplest solution might be to define some Form level variables, and record the default values in an Event like the Form Load event :
// form scoped variables
private Color defaultBackColor;
private Rectangle defaultBounds;
private FormWindowState defaultFormWindowState;
// save the Form default Color, Bounds, FormWindowState
private void Form1_Load(object sender, EventArgs e)
{
defaultBackColor = this.BackColor;
defaultBounds = this.Bounds;
defaultFormWindowState = this.WindowState;
}
Then in the Click Event of your button : reset the defaults :
// restore the defaults on Button click
private void btn_FormReset_Click(object sender, EventArgs e)
{
this.WindowState = defaultFormWindowState;
this.Bounds = defaultBounds;
this.BackColor = defaultBackColor;
}
There are some more powerful ways of doing this involving using the 'Settings feature of Visual Studio (at Design Time and Run-Time) : check them out at :
How to: Create Application Settings Using the Designer
Application Settings Overview
How To: Write User Settings at Run Time with C#
How To: Read Settings at Run Time With C#

Categories

Resources