2

WinForm

public Form1()
{
    Form2 obj = new Form2();
    obj.show(); //shows form2
    this.Close(); //exception crash: because constructor has not yet called `new Form1.show()`
}

In Winform

  1. 'this.close()' will through exception and crash (Cannot dispose object not initialized)
  2. if I don't call .close in Form1, and I close(X) the Form1, Form2 will also get closed because it is an instance within Form1

in WPF, same code:

  1. 'this.close()' will not through exception
  2. If Form1 is closed, Form2 will remain open as MainWindow.

Why is the Difference?

(Edit) I know in Winform I cannot close the same form in constructor because its not yet created, but how is WPF differ with it in constructor call?.

And what if I want the all children windows to get closed if the parent get closed, WinForm way?

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
ADi
  • 219
  • 1
  • 5
  • 17
  • In WinForms, consider using InitializeControls/FormLoaded instead of creating controls (and especially trying to close the same form) in the constructor. – user2864740 Jan 19 '14 at 08:40
  • In WPF, you are closing Window or UserControl? – Rohit Vats Jan 19 '14 at 08:58
  • Have you seen http://stackoverflow.com/questions/3067901/c-sharp-closing-a-form-during-a-constructor – grantnz Jan 19 '14 at 09:23
  • @RohitVats In WPF i'm closing Window – ADi Jan 19 '14 at 11:07
  • @grantnz as i have mentioned, i already know i cant close form in constructor bcoz its not yet created in WinForm, my question is how it differs from WPF, not giving error on close and not being parent of Window created in constructor. – ADi Jan 19 '14 at 11:09

2 Answers2

4

The difference is in how the the Close method for each class is implemented. Despite their similarities in function and appearance, System.Windows.Forms.Form and System.Windows.Window are two completely different classes built around two different architectures.

System.Windows.Forms.Form has been around since .NET 1.0, and is mostly just a thin, easier-to-use wrapper around the native precudral (i.e., non-object oriented) Windows UI library.

System.Windows.Window is part of WPF, which was introduced in .NET 3.0, was an attempt to build a modern UI framework on top of the CLI (rather than simply wrapping the older Windows UI library). So, System.Windows.Window's implementation may be completely different than that of System.Windows.Forms.Form. Additionally, though the operations available on these classes may be superficially similar, they may not be semantically identical. In this sense, Form.Close and Window.Close don't necessarily have exactly the same meaning.

Now, in this particular case, according to the documentation (http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close(v=vs.110).aspx), you are getting this exception because "The form was closed while a handle was being created." If you unpack this statement a bit, what it means is that you made a call to the Close method before the window handle (HWND) for the form was created. This actually has nothing to do with the fact that you're closing the window in the constructor: the constructor for the Form class has already completed at this point. A Form object in .NET represents a native window in Windows OS, which is identified by a window handle (or HWND, which is the type name used in C/C++). However, because creating a window handle is an expensive process, the Form object doesn't actually create the handle until it actually needs it. So, the window handle for the form object doesn't exist until you call Form.Show, Form.HWND, or some other method that forces it to be created. If you had called this.Show() right before this.Close(), no exception would be thrown.

Why is this not the case in System.Windows.Window? My guess is that the Close method in System.Windows.Window is a bit "smarter" and simply skips the step of disposing the handle if it doesn't yet exist. Or, perhaps the window handle is created eagerly, unlike in the Forms implementation.

Whether this difference is entirely intentional is difficult to say. It's not entirely clear whether it makes sense to "close" a Window that's never been shown in the first place, and whether attempting to do so should cause an exception. Its a design choice. It's possible that Microsoft programmers now prefer the semantics of System.Windows.Window.Close over the less forgiving System.Windows.Forms.Close, but that making such a change would not be backwards compatible. Or, its possible no one really noticed or thought about the difference much.

Nimrand
  • 1,748
  • 2
  • 16
  • 29
  • +1 thanks for detailed information. i got the point. I was confused coming from WinForm background, But the real issue remains. In WPF If i close Form1, shoudn't it close Form2 as well bcoz its instance is within Form1. there is no .Dispose() for `Window`. – ADi Jan 19 '14 at 11:19
  • I really wasn't sure what you were trying to accomplish, actually. But, the short answer is no. Just because Form2 was created within the constructor of Form1 doesn't mean that Form2 is "within" Form1. Form2 is its own stand-alone instance of Window. You could hold a reference to Form2 and then override the Form1's Close method to vall Form2.Close explicitly. Or, if you're trying to shutdown the program you could call Application.Current.Shutdown. It might be best if you post a new question and explain what you're actually trying to do. – Nimrand Jan 19 '14 at 11:32
  • Thanks for ur response, actually from ur information and Bsienn's answer i understood what issue i had. actually when i close Window1 i was hoping that it wil close Window2 and will exit program. But in WPF its not the case. – ADi Jan 19 '14 at 11:41
  • I suspect that when it worked that way in Windows Forms, it wasn't actually "by design." Did the second window close because the exception was being thrown which crashed the program? If so, then there's much cleaner ways to accomplish that task. Exceptions aren't meant to be a way to shut down the application. Rather, the program shuts down when an unhandled exception is thrown because thats considered to be safer that leaving the program running in a possibly corrupted state. In fact, you can override that behavior and let the program keep running after the unhanded exception is thrown. – Nimrand Jan 20 '14 at 00:28
1

In WPF you don't manually dispose of WPF objects, they get garbage-collected when there are no more references to them.

As your Form1 have reference to Form2, ur Form1 will stay alive in background hiding the form on .close() untill you close Form2 as well.

You can destroy all objects on closing event of Form1, or you can force you application to Shutdown, which is not good idea unless you handle the unsaved data.

this is very through information on doing it How to exit a WPF app programmatically?

Community
  • 1
  • 1
  • +1 thanks for ur reply, i understood the issue now. as ur answer is correct but sorry cant accept ur anser bcoz i can only 1. My mistake for asking 2 question in one topic. – ADi Jan 19 '14 at 11:43