How to execute code before the splash screen is displayed? - wpf

In my app project I use this to display my splash screen image:
<SplashScreen Include="Images\SplashScreen.png" />
I also use a Mutex to prevent the application being opened more than once. However, even with the Mutex check in the App class constructor the splash screen is displayed before the Mutex check is performed.
Is there some way I can perform the check before the splash screen is displayed to prevent the user seeing it on the second instance?

You can define and show the splash screen programatically, which allows you to control when it is shown and what happens before and after. Add your image with BuildAction set to Resource.
public partial class App : Application
{
protected override void OnStartup(object sender, StartupEventArgs e)
{
// ...execute pre action here.
SplashScreen splashScreen = new SplashScreen(#"Images\SplashScreen.png");
splashScreen.Show(true);
base.OnStartup(e);
// ...other code and post action.
}
}
See the SplashScreen type for more info and please be aware that there two overloads for the Show method. The parameter determines, whether the spalsh screen is automatically closed after the application was loaded. You could pass false and use the Close method to determine yourself when it is closed and execute your action afterwards.

Related

CEF browser showing old content on the window

I was creating a browser window for my WPF application. During the visibility change I am loading the URL, but when I change the URL content and load the same URL it is showing previous content first, then after a blinking it shows the updated data.
void OnWindowVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (!IsBrowserInitialized) return;
if (window.Visibility == Visibility.Visible)
{
Dispatcher.BeginInvoke(new Action(() =>
{
LoadNewUrl();
window.Activate();
}));
}
else
{
Dispatcher.BeginInvoke(new Action(() =>
{
ChromeBrowser.LoadHtml("<html><body><h1></h1></body></html>");
}));
}
}
Suppose the URL contains "ABCD" as data. First time it is showing the correct content. After the update the data becomes "ABCDEF". Now on Load() the initial content is showing then the updated content.
Is there anything else I need to do for avoiding this issue?
I'm not sure what LoadHtml() does, it's not a part of the native CEF API. In any case the blank page is about:blank, i.e. ChromeBrowser.Load("about:blank").
Are you aware of stopping all activities in the hidden browser? It seems to be the issue - you load an empty page and hide the window, the browser stops any activities, then you activate the window and still see an old content, then an empty page causes "blinking", and finally a new content is shown.
You should catch change visibility request, cancel it, load about:blank and hide the window on load completion. The client handler has appropriate events.

Winform app; execute buttons on start

Maybe be a stupid question but say i have an Winform App with 2 clickable buttons (button_1 and button_2), each containing a piece of code. If I open the app, I want to click button_1 then button_2, and close the application. What i am wandering is there any way to insert a method that will call button_1 then button_2 on load (and possibly close the app?) that could be inserted into say Form1_Load?
Don't "click the buttons" automatically. Invoke the logical actions which the buttons invoke automatically. If that logic is currently in the buttons' click events in the code-behind, refactor it into a common location.
For example, your click event might end up with something like:
protected void Button1_Click()
{
SomeObject.DoSomething();
}
Then you can invoke the same action from the form's load event:
protected void Form_Load()
{
SomeObject.DoSomething();
}
Following that, still in the form load event, you can then close the application as well:
protected void Form_Load()
{
SomeObject.DoSomething();
Application.Exit();
}
Though it seems really unnecessary to load up an entire form just to do something without user interaction and then exit. A console application would be much simpler:
static void Main()
{
SomeObject.DoSomething();
}
Then you don't have a UI to worry about, you don't have to attach code to events, you don't even have to forcibly close the application. It'll just execute the code and exit.

A way to refresh a form page from another form page?

I have a Win form application (VS 2010 / C#) and I'm trying to figure out how to refresh pages without a refresh button. Currently I can refresh a page (basically to reset the data bindings) with a refresh button containing code something like this (this.refresh() does not seem to work for some reason):
this.Hide();
AccountSettings AS = new AccountSettings();
AS.ShowDialog();
An example I have is a page with numerous settings including data grids with CellClick events. When I click a cell I can make changes to a database. I hit close to go back to the Settings page but the only way for me to see the changes are to refresh() the page via the button.
So the short of it is, is there any way to refresh a form page from another form page?
For instance, when I click the Save button or close the child window.
Maybe pass the original form as an argument to the second form:
Form2 frm2 = new Form2(this);
And in Form2:
Form1 frm1;
public Form2(Form1 frm1)
{
InitializeComponent();
this.frm1 = frm1;
}
And then have in Form2:
frm1.Update();
Refresh on winform controls repaints the control itself. I find it useful to create a method that just loads my controls with the proper data, and then call it as necessary. (Including Form load)
private void ResetData()
{
//code to update settings
}
If you are showing the form that is closing as a dialog also you can take advantage of that, and check the status of the dialog instead of just opening it.
Form2 dlg = new Form2();
if (dlg.ShowDialog == System.Windows.Forms.DialogResult.OK) {
//code that updates your data
ResetData();
}
If its not a dialog there are a few things you could do and how your application works would make one method better than others. Here is just one example.
If your changes are something you don't need access to data from the other window to update you can handle the closed event of the form you create.
Create a class level variable to hold the form that is opened, so that you can also remove the event handlers you create:
private Form2 frm;
To create an instance of the form, and add the close event handler:
frm = new Form2();
frm.FormClosed += OnForm2Closed;
The event handler method:
private void OnForm2Closed(object sender, FormClosedEventArgs e)
{
ResetData();
frm.FormClosed -= OnForm2Closed;
}

Determine if WPF WebBrowser is loading a page

I have a WPF System.Windows.Controls.WebBrowser control in a Window. A user can enter information and hit a submit button into the webpage displayed by the WebBrowser. After the page posts back it uses a scripting object to communicate with my application. I need to make sure that once the submit button has been pressed, the form doesn't close or otherwise stop waiting for the web page to post back. It would be great if I could check the state of the WebBrowser or its document via a property like "IsLoading" and cancel any actions if it is loading. I didn't see anything like that so I was thinking of setting a flag on the Navigating event and unsetting it on the Navigated or LoadCompleted event, but there is a case where I click a link on the web page (tied to javascript, it doesn't go to a new page) where Navigating is fired, but Navigated and LoadCompleted never fire. Is there a way to determine the state of the browser on demand?
As per MSDN if the Navigating event gets invoked then the Navigated Event will also get fired unless you explicitly Cancel the navigation. I tried the below code-snippet it seems to be working fine. (i.e) whenever the Navigated event is getting fired following Navigating event.
void Window1_Loaded(object sender, RoutedEventArgs e)
{
browser = new WebBrowser();
browser.Navigate(new Uri("http://www.google.com"));
browser.Navigating += new NavigatingCancelEventHandler(browser_Navigating);
browser.Navigated += new NavigatedEventHandler(browser_Navigated);
}
void browser_Navigating(object sender, NavigatingCancelEventArgs e)
{
Console.WriteLine("Loading Webpage !!");
}
void browser_Navigated(object sender, NavigationEventArgs e)
{
Console.WriteLine("Webpage Loaded !!");
}
If this is not what you are looking for, then provide the webpage URL in which you are facing the issue.
No, there does not appear to be a way to query the WPF browser's status on demand. I settled on my original idea of setting my own flag in the Navigating event handler and unsetting it in the Navigated event handler. It was not working reliably for me because there was a script that canceled navigation (javascript:void(0)).

Prevent Multiple Form Instances

How do I prevent Multiple forms from opening?
I do .show on the form but the user can click the main form and the button again and another instance of form opens.
Two options, depending on what you need:
Use ShowDialog instead of Show, which will open a modal window. This is the obvious solution if you don't need your main form to be active while the child form is open.
Or keep track of the window you opened already in the main form and do nothing if it's already open. This will be needed if you want the user to be able to use the main form while the child form is already open, maybe to open other forms.
do something like:
SingleForm myform = null;
void ShowMyForm_Click(object sender, EventArgs e)
{ if (myform == null)
{
myform = new SingleForm();
}
myform.Show();
myform.BringToFront();
}
Force your form object to adhere to the singleton pattern
I prefer to use Generics and lazy loading to handle my forms. Since all of my forms inherit from a base class, I can use the same method to bring forms to the front, send them to the back, destroy them, start them, etc.
If you keep a form manager class that's responsible for managing any loaded forms, you can bring whatever form to the front that you want, or prevent specific forms from being able to come back unless certain criteria are met.
public void LoadForm<T>() where T : MyNameSpace.MyBaseForm
{
// Load all your code in this joint and just call it when you
// need a form. In here, you can determine if a copy of the form
// already exists and then bring it forward or not
}
Disable the main form until the child form goes away, or disable the button.
button_onClick(object Sender, EventArgs e)
{
Button btn = sender as Button;
btn.Enabled = false;
Form myform = new MyForm();
myform.Show();
}
Of course, you really should be using form.ShowDialog() rather than form.Show() if you want modal behavior.

Resources