How to close the home window - c#

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>

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

When is a WPF window usable as an Owner?

We have an intermittent problem where an InvalidOperationException is being thrown in the ShowDialog method of a dialog window. The suspect cause is because the dialog is setting its Owner to a window which hasn't been displayed yet. This conclusion is based on the following:
The main application window (intended Owner of the dialog) instantiates and invokes ShowDialog on the dialog during its Loaded handler.
The dialog sets its Owner to the application window during its constructor
The documentation for Window.Owner says it will throw an InvalidOperationException if set to a window that hasn't been displayed yet.
We assume the (main application window) Loaded event may be fired before the window is displayed.
The exception is usually not thrown because the main application window is shown by the time the ShowDialog call is made. When the host system is under stress, the application window "Show" may be delayed, so that when ShowDialog is called, it isn't yet ready to be used as an Owner.
The question is: is this true? If so, what window event or override can be used to reliably fire after it has been displayed, so that the window may then be reliably used as the dialog's Owner, regardless of system conditions?
<Window x:Class="MyApplication.MyMainWindow"
... etc...
Loaded="OnLoaded">
... etc...
</Window>
class MyMainWindow : Window
{
private void OnLoaded(object sender, RoutedEventArgs e)
{
var dialog = new MyDialog(Application.Current.MainWindow);
dialog.ShowWindow();
}
}
class MyDialog: Window
{
public MyDialog(Window window)
{
Owner = window;
}
}
The question is: is this true?
Looks that way from inspecting the code. Programming WPF by Chris Sells & Ian Griffiths also states that the Loaded event is raised just before the window is shown.
What window event or override can be used to reliably fire after it has been displayed, so that the window may then be reliably used as the dialog's Owner, regardless of system conditions?
The ContentRendered event will be fired once, upon showing the window. I think it would be the best choice for your situation.
You can also force a Window's hWnd to be created at any time, though I'm not sure that would be enough to avoid the exception, as a created window isn't necessarily 'shown'. Still, it's a useful thing to know if you ever end up calling Win32 methods related to window management:
new WindowInteropHelper(window).EnsureHandle()

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

Window management - opening, closing & re-opening non-modal forms?

In pseudocode, this is what I am trying to do from a main window, with many non-modal sub-windows that can be opened and closed independently of the main window.
(Think "preferences" or "find")
On pressing "OPEN WINDOW"
STEP 1: If window does not exist, create it.
STEP 2: Window now exists, so bring it to the front & make it visible.
(Step 2 is NB in case OPEN WINDOW is pressed while window is already open - I don't want multiple instances of it, just bring it to the front.)
On pressing "CLOSE WINDOW"
STEP 3: Close the window
ALT STEP 3: Hide the window
This is the code I have tried. I got as far as being able to open the window, and bring it to the front if OPEN WINDOW is pressed again while the window is open. However, once I close the window, I CANNOT get it to open a second time. I get an error stating that Window.Show() cannot be used once the window is closed.
public static void OpenWindowOnce(Window windowToOpen)
{
foreach (Window n in Application.Current.Windows)
{
//Checks if the window is already open, and brings it to the front if it is
if (n.GetType() == windowToOpen.GetType())
{}
else
{ windowToOpen.Show(); }
}
windowToOpen.Activate();
}
Where am I going wrong in my code/logic? Thank you, I am pretty new to coding and have spent weeks trying to get this right.
You cannot use a Window that has been closed because its resources are disposed at that time. The solution is to simply create a new Window each time that you want to display it.
I can see that you are passing in a Window object and then trying to find the particular type of Window... in this case, you can use reflection to instantiate your Windows from their Type. In particular, please see the Activator.CreateInstance Method page on MSDN. You could use it something like this:
public static void OpenWindowOnce(Window windowToOpen)
{
foreach (Window n in Application.Current.Windows)
{
//Checks if the window is already open, and brings it to the front if it is
if (n.GetType() == windowToOpen.GetType()) { ... }
else
{
windowToOpen = Activator.CreateInstance(typeof(YourWindow)) as YourWindow;
windowToOpen.Show();
}
}
windowToOpen.Activate();
}

Wpf minimizes Window?

I have a main Window.Then if you touch settings button a new modal Window is shown with some options..Then you click an option and a new Window (lets call it "Settings") is shown.Both windows have as owner the main Window. Our new window(Settings) may open new window having itself as owner for example if you want to add a new staff member.And here is the problem. When you close the new window and then close Settings window the main Window is minimized... However this doesnt happen if Settings window dont open any other window...
this is how i show the forms
UserForm f = new UserForm();
f.Owner = this;
f.Show();
Use MainWindow.Activate() on close of Child Window.
it should work
I ran into the same problem and found an apt solution here.
Set the window owner to null before the Settings window closes.
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
Owner = null;
}
Can't you catch when the window is closed (OnFormClose I think) and then unminimise your main window?

Categories

Resources