How to close a window but still have app current active? - c#

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.

Related

Switching from one window to another in WPF and making it active

I'm pretty new to WPF and I'm trying to make a database system. What I currently have is a Login Window. When you enter the user and password you are supposed to go to another window StudentInfoSystem . The code I used is pretty basic and common.
var info = new StudentInfoSystem.MainWindow();
info.Show();
this.Close();
So, what this would do, is after you press the login button, you get transferred to StudentInfoSystem and the login window closes. The problem I have with Show() is that it opens a window and immediately returns, right? It doesn't wait for the new window to close. So, my question is how can I open a new window and WORK with it? When I say work, I meant to show out information in my textboxes (In the NEWLY opened window) depending on the role the user has, etc...
I'm guessing the above code is in the button click handler for the Login Window, which would make the Login Window the parent of the StudentInfoSystem window.
Since WPF will close the parent and any child(ren) window(s) when closing the parent window, your StudentInfo window will also close when calling
this.Close();
One option might be to instead call
this.Hide();
but without seeing how the rest of your app is set up, not 100% sure this is the best approach.
Perhaps see these SO questions:
wpf-create-sibling-window-and-close-current-one
how-to-close-current-window-in-code-when-launching-new-window
Try window.Activate() to focus the new window and/or [any element].Focus() to focus any element within window.
As I understand, this should do what you want:
info.ShowDialog();
You could also check ShutdownMode property. I would rather say, login window is sth you want to close after login, but do what you want :). Usage of ShutdownMode property:
public partial class App : Application
{
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
this.ShutdownMode = System.Windows.ShutdownMode.OnLastWindowClose;
}
}

How to ShowDialog two windows sequentially with APP.xaml Startup function

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.

App main window, how is it and the main use of this?

I have an application that has the start up window for the login, if the login is correct, it open the main window of the application.
When the login is correct, I open the new window in this way (I am using MVVM pattern):
PrincipalViewModel miPrincipalViewModel = new PrincipalViewModel();
PrincipalView miPrincipalView = new PrincipalView();
miPrincipalView.DataContext = miPrincipalViewModel;
App.Current.MainWindow.DataContext = null;
App.Current.MainWindow.Close();
miPrincipalView.Show();
In this case I don't set the new main window. Another option is this code:
PrincipalViewModel miPrincipalViewModel = new PrincipalViewModel();
PrincipalView miPrincipalView = new PrincipalView();
miPrincipalView.DataContext = miPrincipalViewModel;
App.Current.MainWindow.DataContext = null;
App.Current.MainWindow.Close();
App.Current.MainWindow = miPrincipalView;
miPrincipalView.Show();
In this second case, I set the main window property to the main window of the application, because the login window is closed.
But I don't see any difference in the behavior in both cases, so I am wondering what is really MainWindow and the use and meaning that is has.
Thank you.
In the first case you no longer have an actual MainWindow but that shouldn't be an issue unless you rely on the Application.Current.MainWindow property to return a valid reference to a window somewhere in your application or if you have set the Application.ShutdownMode property to OnMainWindowClose.
The default value is OnLastWindowClose which means that your application will shut down as expected when you close the new window anyway.
As the documentation on MSDN says "the lifetime of some applications may not be dependent on when the main window or last window is closed, or may not be dependent on windows at all.".
Here is part about what is App.Current.MainWindow from MSDN
MainWindow is automatically set with a reference to the first Window
object to be instantiated in the AppDomain. You can specify a
different main window by setting MainWindow assigning another Windows
object to the MainWindow property. If the ShutdownMode property of the
Application object is set to OnMainWindowClose, closing the main
window causes the application to shut down. It is possible to set the
MainWindow property from XAML, if an application's main window is not
the window that is produced by setting the StartupUri property in
XAML. The two limitations of the XAML approach are: You can specify
either a XAML-only Window or a XAML-only NavigationWindow as the main
window. You must set the Visibility property of the window you
specify, otherwise it won't be shown. The reference to the first
Window object to be instantiated is also added as the first item to
the Windows collection. If MainWindow is subsequently set with a
reference to a different Window, the position of the item with the
reference to the main window will change, while the order of items in
Windows remains the same. Consequently, always use MainWindow to refer
to the main window instead of the first item in Windows.
I think that you just need to set App.Current.ShutdownMode to ShutdownMode.OnExplicitShutdown before App.Current.MainWindow.Close(); and call App.Current.Shutdown when you will want to close the application.
MSDN Application.ShutdownMode

Closing all windows in WPF after one has been closed

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

How to close the home window

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>

Categories

Resources