Sign in to follow this  
Talib

C# Switching between windows (and other questions)

Recommended Posts

Ok, I am C++ coder trying my hand at C#. I want to have one window to select some options and then close it and display my main window. I did some searching and the two main methods seem to be: 1) Two Application.Run()s, thus having two programs. I don't like this personally as it just doesn't feel right. 2)Showing and hiding the windows. This is quite a workable method, but what was bugging me was that the first window will only be used for a fraction of the Applications lifetime and the memory will never be freed (Oh I have an obsession with using as little memory as possible, probably cause I work with Microprocessors). I did find another method though on MSDN (I think):
using System;
using System.Windows;

namespace CSharp
{
    public class EntryPoint
    {
        // All WPF applications should execute on a single-threaded apartment (STA) thread
        [STAThread]
        public static void Main()
        {
            CustomApplication app = new CustomApplication();
            app.Run();
        }
    }

    public class CustomApplication : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);

            Window window = new Window();
            window.Show();
        }
    }
}


A couple of questions though: 1) Why is nobody recommending this? (Too complicated for newbies?) 2) What do they mean by "// All WPF applications should execute on a single-threaded apartment" 3) Where is the best place to delete the first window? (IE in the OnClose() method of the first window or the OnCreate() of the second window? or where?) 4) Where is the best place to new the second window? (IE in the OnClose() method of the first window?) Thanks for all the help.

Share this post


Link to post
Share on other sites
Quote:
Ok, I am C++ coder trying my hand at C#. I want to have one window to select some options and then close it and display my main window.


I am presuming this means we have two System.Windows.Forms.Form derived classes, e.g. SettingsForm and MainForm.


Quote:

1) Two Application.Run()s, thus having two programs. I don't like this personally as it just doesn't feel right.


Uhm no, it doesn't ;)


Quote:

2)Showing and hiding the windows. This is quite a workable method, but what was bugging me was that the first window will only be used for a fraction of the Applications lifetime and the memory will never be freed


The memory will be freed upon the first garbage collector cycle; you can be lazy.


Quote:

A couple of questions though:

1) Why is nobody recommending this? (Too complicated for newbies?)


If my assumption of having two window classes is right, nobody recommends this because there's actually a very simple trick to it:


// This is the form you want displayed for the settings
public partial class SettingsForm: Form
{
// Example property, normally set by some GUI elements on
// the form
private int option1 = -1;
public int Option1 { get { return option1; } }

public SettingsForm()
{
InitializeComponent();

option1 = 872; // for now, set in ctor
}
}

public partial class MainForm: Form
{
// Link this event in the designer
private void MainForm_Load( object sender, EventArgs e )
{
// This creates a temporary instance that will be freed
// when the using clause scope ends.
using ( SettingsForm frmSettings = new SettingsForm() )
{
frmSettings.ShowDialog();

// Extract your setting form's properties here
MessageBox.Show( frmSettings.Option1.ToString() );
}
}
}




Quote:

2) What do they mean by "// All WPF applications should execute on a single-threaded apartment"


WPF = Windows Presentation Foundation (formerly Avalon), for rich GUIs, see http://en.wikipedia.org/wiki/Windows_Presentation_Foundation

Single-threaded apartment, as opposed to multi-threaded apartment or free threading, creates an 'apartment' (isolated memory space) for each thread in the application. The application decides what thread executes when and communication is done through the message queue. In an MTA model there is a single apartment for all threads and the programmer has to do the critical section management and synchronization and no message queue is used.


Quote:

3) Where is the best place to delete the first window? (IE in the OnClose() method of the first window or the OnCreate() of the second window? or where?)


Done when you go out of scope (using clause).


Quote:

4) Where is the best place to new the second window? (IE in the OnClose() method of the first window?)


This approach creates the window in the primary form's form_load, where the form is already constructed (in your Application.Run( new MainForm() ) call) but not yet shown because we're interrupting with another form.

Share this post


Link to post
Share on other sites
Thanks a lot

You have hit the nail on the head. The way you describe it is just the way I want to use it.

Still a lot of new concepts to grasp. I am not sure if I like this garbage collector thingy. I hate not being in control. But thats probably something I will need to learn to live with.

Another question though. According to the MSDN:

Quote:
When a form is displayed as a modal dialog box, clicking the Close button (the button with an X at the upper-right corner of the form) causes the form to be hidden and the DialogResult property to be set to DialogResult.Cancel. Unlike modeless forms, the Close method is not called by the .NET Framework when the user clicks the close form button of a dialog box or sets the value of the DialogResult property. Instead the form is hidden and can be shown again without creating a new instance of the dialog box. Because a form displayed as a dialog box is not closed, you must call the Dispose method of the form when the form is no longer needed by your application.



public void ShowMyDialogBox()
{
Form2 testDialog = new Form2();

// Show testDialog as a modal dialog and determine if DialogResult = OK.
if (testDialog.ShowDialog(this) == DialogResult.OK)
{
// Read the contents of testDialog's TextBox.
this.txtResult.Text = testDialog.TextBox1.Text;
}
else
{
this.txtResult.Text = "Cancelled";
}
testDialog.Dispose();
}




Will the using keyword still dispose of the window correctly?

Share this post


Link to post
Share on other sites
Quote:
Will the using keyword still dispose of the window correctly?


Yes. You can only use IDisposable implementing types in a using clause. The reason for this is that Dispose() is automatically called upon leaving the using scope.

See http://msdn2.microsoft.com/en-us/library/yh598w02.aspx

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this