private void AppToStart(object sender, StartupEventArgs e)
{
var startUpWindow=new StartUpWindow();
startUpWindow.ShowDialog();
var mainWindow = new MainWindow();
mainWindow.ShowDialog();
}
I have wrote these commands to ShowDialog MainWindow after StartUpWindow.
But when I close the StartUpWindow instance, the entire application closes.
What's wrong with my code?
If there is a better way to doing what I want instead of creating an instance and calling his ShowDialog method please tell me.
You could start by checking your Application.ShutdownMode property to see what it is set to. It can be found in App.xaml.
Per MSDN:
A ShutdownMode of OnMainWindowClose causes Windows Presentation Foundation (WPF) to implicitly call Shutdown when the MainWindow closes, even if other windows are currently open.
after i added ShutdownMode="OnExplicitShutdown" in APP.xaml properties , my app closing with Application.Current.Shutdown(); method.
Related
I'm using a Mutex to ensure that only one instance of the application is able to run at any given time.
I allow the user to close the MainWindow but I keep the application running with the ability to open another instance of the MainWindow by double clicking the Notify Icon in the system tray.
What I want to do is create a new instance of the MainWindow in the currently running instance of the application (the one that was started first), if the MainWindow is not currently opened, whenever the user attempts to run another instance of the application.
I've found that I'm able to restore a current instance of the MainWindow from another instance of the application by using the Windows API messaging system, but if the MainWindow is closed, the WndProc function naturally doesn't receive any messages, so I can't use that.
I also thought about calling Hide() on the window when the close button is clicked instead of actually closing the window instance, but I can't get the window fade animation to display when using Show(). From the other posts I've seen about the Show() function, the animation only displays the first time you show the window after it has been created.
Here's the code for my App.xaml.cs, if it helps:
protected override void OnStartup(StartupEventArgs e)
{
bool singleInstance;
mutex = new Mutex(true, UniqueMutexName, out singleInstance);
if (!singleInstance)
{
NativeMethods.PostMessage((IntPtr)NativeMethods.HWND_BROADCAST, NativeMethods.WindowsMessage.WM_INSTANCEATTEMPT, IntPtr.Zero, IntPtr.Zero);
Current.Shutdown();
}
else
{
// create the NotifyIcon if this is the only instance
NotifyIcon = (TaskbarIcon)FindResource("NotifyIcon");
}
base.OnStartup(e);
}
In the above code, the window message just checks if the window instance is minimized and restores it if so. Any other ideas of things I could try?
Im using WPF to make a simple budget app for myself as practice and I can't figure out how to change which window opens first. I mean when you start the program , right now it opens the MainWindow, but I want it to open another window. I have tried this in my app.xaml.cs file:
public partial class App : Application
{
void App_Startup(object sender , StartupEventArgs e)
{
GetNameWindow getNameWindow = new GetNameWindow();
getNameWindow.Show();
}
}
which I read was a way to do it but it doesn't work for me. I'm using c# and visual studio 2017. Thanks!
To change the startup window, open App.xaml and replace "MainWindow.xaml" with your window:
StartupUri="GetNameWindow.xaml">
For what you were trying to do, you would need to remove StartupUri="MainWindow.xaml" and instead use Startup="App_Startup" and then it would call your event Handler at startup.
suppose i have 2 windows: InputWindow and DisplayWindow
Currently:i want to use InputWindow to hold data via an App variable
// in InputWindow
(App.Current as App).u_id = obj.id;
where u_id is the object i defined in app.xaml.cs and obj.id is the input variable in InputWindow.
However when i close InputWindow and display DisplayWindow:
// in InputWindow
DisplayWindow window = new DisplayWindow();
window.Show();
Application.Current.MainWindow.Close();
The app also kill the data in the InputWindow.
So my question is:
Is there a way to keep the data via from the closed Window to the open Window?
Set Application.ShutdownMode to ShutdownMode.OnExplicitShutdown.
You can do this in you App.xaml, or anywhere else in C#.
<Application ... ShutdownMode="OnExplicitShutdown>
...
</Application>
Or in your App.xaml.cs:
ShutdownMode = ShutdownMode.OnExplicitShutdown;
Or somewhere else:
Application.Current.ShutdownMode = ShutdownMode.OnExplicitShutdown;
To shut down your application, you will need to call Application.Shutdown():
Application.Current.Shutdown();
You can also set Application.ShutdownMode to OnLastWindowClose, to shut down your application when the last window is closed (rather than when the main window is closed). You can do this in any of the ways described above.
However, it sounds like the only reason you want to keep your main window alive is so that you can use it as a data store. I recommend using a separate object as your data store, and referencing it both from your InputWindow and your DisplayWindow.
Application.Current.MainWindow.Hide();
You can hide the window using this line... or you can pass the information that you want to use into the new window using the constructor.
DisplayWindow window = new DisplayWindow(object myObject);
That constructor must have the information you want passed but this can solve the issue as well.
Is there any way I could close all windows after the user closes one of them, and here is the important part: without using App.Current.Shutdown(), but rather by invoking close on remaining windows individually?
My idea was to just invoke close on each of the remaining windows in the Window_Closing event handler method. There's one problem, though. Suppose I have two window classes, A and B. I create one instance of A and B - a and b respectively. If I close window A, then it invokes the Window_closing event handler method and calls b.close() there. Then in the B class (A and B are window classes, they both inherit from Window) Window_closing method is invoked (because I've just called B.close()), and B::Window_closing calls a.close() and it results in exception cause I've already closed a.
What is the right way to solve this?
If you are interested in having a "main window" and "tool windows", so that closing the main window closes all of them and closing tool windows does, well, only just that - then in the App.xaml there's a friendly option just for that!
That's Application.ShutdownMode
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
ShutdownMode="OnMainWindowClose"
>
</Application>
Note that here, the "MainWindow" in question, is the main window the application starts with (or the one you set as main, if you played with that during the app's lifetime).
EDIT: afterthought: That will of course close all the windows, but I'm not actually sure if it calls normal "Close", or just shutsdown the whole application. Sorry, you'd need to check it for yourself. If you're interested in my opinion, that's the way you should/could do that easily, and if you really-really-need to shutdown the app by "Close()"ing every window, then I sense you're doing something wrong here, as if I remember correctly, "Window.Close()" may be cancelled.
EDIT2: yup, Window.Close() can be cancelled. Please see this article:
Closing a window causes the Closing event to be raised. If the Closing
event isn't canceled, the following occurs: (...)
So looping over the window collection and calling 'Close' doesn't really guarantee that the windows will really be closed and the app may still be left running afterwards.
Something like this:
private static bool WindowsClosing;
public static void CloseAllWindows()
{
if(WindowsClosing) return;
WindowsClosing = true;
var windows = Application.Current.Windows;
foreach (var wnd in windows.OfType<Window>())
{
wnd.Close();
}
}
And call that method from your Window_Closing (or rather Window_Closed if you don't need to cancel) events
Handle Window.Closedevent instead of Window.Closing which would be closing all the opened windows other than MainWindow. I am not calling Close method for MainWindow because this is the main thread which will cause application terminating.
private void Window_Closed(object sender, EventArgs e)
{
var windows = Application.Current.Windows;
foreach (var item in windows)
{
if ((item as Window).Title.ToLower() == "mainwindow") continue;
(item as Window).Close();
}
}
I'm creating a wpf application in c#, I know to close/open a window you have to use the .Close() and .Show() methods but for some reason the home screen, the first window that appears when I launch the application, won't close.
Home window1 = new Home();
window1.Close();
Name window2 = new Name();
window2.Show();
Window2 appears, but window1 won't close. What's the problem.
Where is your code for showing window1? If you show your home window somewhere else in your code, you need to use that reference in order to close it. Making a new Home object and calling its Close method will not close a window shown using another Home object.
Presumably because if you close the window you'll close the application.
If you just want to hide the main window use the window.Hide() method.
This from the help on Window.Close:
A Window can be closed using one of
several, well-known, system-provided
mechanisms located in its title bar,
including:
ALT+F4.
System menu | Close.
Close button.
A Window can also be closed using one
of several well-known mechanisms
within the client area that are
provided by developers, including:
File | Exit on a main window.
File | Close or a Close button on a
child window.
UPDATE
Tormod Fjeldskår has a good point in his answer. I assumed that the code was given as an example rather than being what was actually being used.
This is a bug in WPF. Window.Close will fail silently if the SourceInitialized event has not yet occurred. Subsequent calls to Window.Close will also fail.
https://connect.microsoft.com/WPF/feedback/ViewFeedback.aspx?FeedbackID=299100
For a workaround, add this to your Window:
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
// check if we've already been closed
if (m_bClosed)
{
// close the window now
Close();
}
}
protected override void OnClosing(CancelEventArgs e)
{
base.OnClosing(e);
// make sure close wasn't cancelled
if (!e.Cancel)
{
// mark window as closed
m_bClosed = true;
// if our source isn't initialized yet, Close won't actually work,
// so we cancel this close and rely on SourceInitialized to close
// the window
if (new WindowInteropHelper(this).Handle == IntPtr.Zero)
e.Cancel = true;
}
}
bool m_bClosed;
Or you could have Window2 be the main window (you can change this in app.xaml in the StartUpUri property) and either have Window2 show and close Window1 or not show Window1 at all.
<Application x:Class="Invitrogen.TheGadget.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window2.xaml">
</Application>