Monitoring ChromiumWebBrowser control initialization - winforms

We use the CefSharp's ChromiumWebBrowser control (83.4.20) in Windows Forms application.
We hook up the IsBrowserInitializedChanged event to know when the browser control was initialized so we can start loading our web application. Occasionally this event is not fired at all so our application will be stuck and won't load the web app.
In case the app is stuck in initializing the ChromiumWebBrowser control, the WebView_IsBrowserInitializedChanged or WebView_LoadError are not fired:
public MainForm()
{
InitializeComponent();
this.webView.IsBrowserInitializedChanged += WebView_IsBrowserInitializedChanged;
this.webView.LoadError += WebView_LoadError;
}
private void InitializeComponent()
{
this.webView = new CefSharp.WinForms.ChromiumWebBrowser();
// usual WinForms initialization code from the designer
// ...
}
private void WebView_IsBrowserInitializedChanged(object sender, EventArgs e)
{
if (this.webView.IsBrowserInitialized)
{
this.webView.Load(this.ApplicationUri.AbsoluteUri);
}
}
private void WebView_LoadError(object sender, LoadErrorEventArgs e)
{
// handle the error
// ...
}
Are there any other events we can subscribe to to monitor the state of CefSharp and the browser control which would aid as in troubleshooting this situation?

Related

Enable drag drop on a winform application

I would like to enable drag-and-drop feature for my winforms application. The main UI form is an MDI container.
I added the following code to the main form
mainuiform.AllowDrop = true;
mainuiform.DragDrop += OnDragDrop;
mainuiform.DragEnter += OnDragEnter;
The drag-and-drop does not work in the body of the application and works only on the header of the application.
Then I read that the drag-and-drop should be enabled for each child component then only we can drop a document anywhere on the application ui. This is painful as the various forms in the MDI are created by different teams.
How do I achieve this?
Add event handler to the main form (constructor)
Add event handler to all child component of the main form (in load event)
Add event handler to mdi child and its all children component (MdiChildActivate event)
since I am using DevExpress there are some DevExpress methods (there should be equivalent with winforms).
public MainMdiForm() {
RegisterDragDropEvents(this);
MdiChildActivate += OnMdiChildActivate;
}
// load event handler
private void MainMdiFormLoad(object sender, EventArgs e)
if(sender is XtraForm form)
form.ForEachChildControl(RegisterDragDropEvents);
}
private void RegisterDragDropEvents(Control control)
{
control.AllowDrop = true;
control.DragDrop += OnDragDrop;
control.DragEnter += OnDragEnter;
}
private void DeRegisterDragDropEvents(Control control)
{
control.DragDrop -= OnDragDrop;
control.DragEnter -= OnDragEnter;
}
private void OnMdiChildActivate(object sender, EventArgs e)
{
if (sender is XtraForm form)
{
// since the same event is called on activate and de active, have observed that ActiveControl == null on de active
// using the same to de register
if (form.ActiveControl == null)
{
form.ForEachChildControl(DeRegisterDragDropEvents);
}
else
{
form.ForEachChildControl(RegisterDragDropEvents);
}
}
}
void OnDragDrop(object sender, DragEventArgs e)
{
// take action here
}
void OnDragEnter(object sender, DragEventArgs e)
{
// additional check and enable only when the file is of the expected type
e.Effect = DragDropEffects.All;
}
Drag drop works on the application with this code.

cefsharp winform browser , how to get properly hole website loaded event (some event not working )

My project in using cefsharp winform browser
There are not properly working OnLoadingStateChanged event
after opening some website this event 2 or 3 times trigger
I have no idea how to use properly code for hole website properly loaded then i get event
i am using VS 2015 Community
package version of cefsharp
all packages installed screenshot image
project dot net framework is 4.6.2
This is code i am using
public partial class BrowserWin : UserControl
{
public ChromiumWebBrowser browser;
public bool IsLoading;
public BrowserWin() {
InitializeComponent();
CefSharpSettings.LegacyJavascriptBindingEnabled = true;
browser = new ChromiumWebBrowser();
browser.Dock = DockStyle.Fill;
this.Controls.Add(browser);
//Wait for the page to finish loading
browser.LoadingStateChanged += OnLoadingStateChanged;
browser.FrameLoadStart += Browser_FrameLoadStart;
browser.FrameLoadEnd += Browser_FrameLoadEnd;
}
private void OnLoadingStateChanged(object sender, LoadingStateChangedEventArgs args)
{
if (args.IsLoading == false)
{
IsLoading = false;
}
}
private void Browser_FrameLoadStart(object sender, FrameLoadStartEventArgs e)
{
IsLoading = true;
}
private void Browser_FrameLoadEnd(object sender, FrameLoadEndEventArgs e)
{
}
}

Is there a way to keep additional windows active when showing a modal window?

I'm afraid the answer is probably no...but some background. To draw a custom border on a window where the sizing logic works beyond the visible border (as it does on windows 10) I added layered windows around the edges to capture the messages and then forward them to the central window. This worked great until the form was shown modaly, at which point all the edge windows were automatically disabled. Obviously this is by design...but I'm not sure if there is some way around it. I tried making the edge windows owned by the central window, but that didn't work.
Or maybe there is a better approach entirely.
Here's a sample of the issue:
public partial class Form1 : Form
{
public Form1()
{
}
protected override void OnClick(EventArgs e)
{
base.OnClick(e);
Form f2 = new Form();
f2.Text = "Non Modal";
f2.Show();
Form f3 = new Form();
f3.Text = "Modal";
f3.ShowDialog(this);
}
}
I think you can fake the modal window, so that it is not modal but disable the caller. I used this in a own project. I did it this way:
//Setup small Interface
public interface IDialog
{
//Our own Event which tell the caller if the Dialog is active/inactive
public event DialogChangedEventArgs DialogChanged;
}
//Setup EventArgs for our own Event
public class DialogChangedEventArgs : EventArgs
{
public bool DialogActive{get;}
public DialogChangedEventArgs(bool dialogActive)
{
DialogActive = dialogActive;
}
}
//Setup the Form which act as Dialog in any other form
public class Form2 : Form, IDialog
{
public event EventHandler<DialogChangedEventArgs> DialogChanged;
//If this Form is shown we fire the Event and tell subscriber we are active
private void Form2_Shown(object sender, EventArgs e)
{
DialogChanged?.Invoke(this, true);
}
//If the user close the Form we telling subscriber we go inactive
private void Form2_Closing(object sender, CancelEventArgs e)
{
DialogChanged?.Invoke(this, false);
}
}
public class Form1 : Form
{
//Setup our Form2 and show it (not modal here!!!)
private void Initialize()
{
Form2 newForm = new Form2();
newForm.DialogChanged += DialogChanged;
newForm.Show();
}
private void Form2_DialogChanged(object sender, DialogChangedEventArgs e)
{
//Now check if Form2 is active or inactive and enable/disable Form1
//So just Form1 will be disabled.
Enable = !e.DialogActive;
}
}
It's really simple. Just use an event to tell your first Form: Hey iam second Form and active. Then you can disable the first Form with while second is active. You have the full control which forms are active or not. Hope this helps.

How to logout on app exit in Silverlight application?

I have a silverlight application with custom form authentication.
How i can logout application when the browser window is closed?
I tried something like this:
public App()
{
Startup += ApplicationStartup;
Exit += Application_Exit;
UnhandledException += ApplicationUnhandledException;
var webContext = new WebContext {Authentication = new FormsAuthentication()};
ApplicationLifetimeObjects.Add(webContext);
InitializeComponent();
}
private void ApplicationStartup(object sender, StartupEventArgs e)
{
Resources.Add("WebContext", WebContext.Current);
RootVisual = new MainPage();
}
private void Application_Exit(object sender, EventArgs e)
{
WebContext.Current.Authentication.Logout(false);
}
but this didn't work. Ewery time I close the browser, I receive the exception An AsyncCallback threw an exception without any details.
How can I handle this problem?
you could call an ajax call on the page with onbeforeunload, forget the idea to call logoff with silverlight whilst it is closing.

Global handling exception in WPF app with Caliburn.Micro

Hi I try implement solution from this site im my WPF app for global exception handling.
http://www.codeproject.com/Articles/90866/Unhandled-Exception-Handler-For-WPF-Applications.aspx
I use Caliburn Micro as MVVM framework. Service I have in external assembly and it is injected in view model class with MEF.
Here is my implementation for global exception handling in WPF app.
App.xaml
DispatcherUnhandledException="Application_DispatcherUnhandledException"
Startup="Application_Startup"
App class:
public partial class App : Application
{
private IMessageBox _msgBox = new MessageBoxes.MessageBoxes();
public bool DoHandle { get; set; }
private void Application_Startup(object sender, StartupEventArgs e)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
}
private void Application_DispatcherUnhandledException(object sender,
System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
if (DoHandle)
{
_msgBox.ShowException(e.Exception);
e.Handled = true;
}
else
{
_msgBox.ShowException(e.Exception);
e.Handled = false;
}
}
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
var ex = e.ExceptionObject as Exception;
_msgBox.ShowException(ex);
}
}
Service method from external assembly:
public void ServiceLogOn()
{
try
{
}
catch (Exception ex)
{
throw ex;
}
}
This service method is call in view model class for example on button click event:
[Export(typeof(ILogOnViewModel))]
public class LogOnViewModel : Screen, ILogOnViewModel
{
public void LogOn()
{
_service.ServiceLogOn();
}
}
I run WPF app in Visual Studio and produce exception with message "Bad credentials" in ServiceLogOn method.
I expect that I see the message box with the exception.
But Visual Studio stop debuging app and show exception in service method in service project.
So I try run WPF from exe file and produce same exception in ServiceLogOn method.
I get this error:
Exception has been throw by target of an invocation.
Any exception from view model class is not handled in methods:
Application_DispatcherUnhandledException
or CurrentDomain_UnhandledException.
in App class.
What I do bad?
EDITED with Simon Fox’s answer.
I try implement in MEF bootstraper advice of Simon Fox’s, but I still something do wrong.
I move handle logic for exception to OnUnhandledException method in bootstraper class.
Here is my code from bootstraper class:
public class MefBootStrapper : Bootstrapper<IShellViewModel>
{
//...
private IMessageBox _msgBox = new MessageBoxes.MessageBoxes();
public bool DoHandle { get; set; }
protected override void OnUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
{
if (DoHandle)
{
_msgBox.ShowException(e.Exception);
e.Handled = true;
}
else
{
_msgBox.ShowException(e.Exception);
e.Handled = false;
}
}
//...
}
I bind some method from view model on button and throw new exception. Something like this:
public void LogOn()
{
throw new ArgumentException("Bad argument");
}
But result is sam, I test app out of Visual Studio and get this exception.
Exception has been throw by target of an invocation.
Caliburn.Micro has built in support for hooking unhandled exceptions. The Bootstrapper class (which every Caliburn project requires) sets this up for you and provides the virtual OnUnhandledException method.
In your custom BootStrapper you must override OnUnhandledException to perform any custom actions for unhandled exceptions in your app. Note that you will most likely have to marshal actions such as displaying a message box to the UI thread (Caliburn enables this easily via Execute.OnUIThread).
You may also have an issue in the way your service moves exceptions to the client, but without any details of how the service is implemented/hosted/etc I cannot help. Are you using WCF to do SOAP? Are you using FaultContracts?

Resources