Reputation: 2297
I have a Visual C# 2010 application, and it has one main form called MainWnd
with other tool windows and dialogs. I want the other tool windows to be able to 'talk' to the main form, and call its methods. But that requires an instance of MainWnd
, and since there will only be one of these forms created at any given time there is no reason while I should enumerate through all instances of MainWnd
or look for the first one. So I want my main application form MainWnd
to be a singleton so other windows can easily call code from it.
Here is the code of the main form that I would like to make a singleton:
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace MyLittleApp
{
public partial class MainWnd : Form
{
public MainWnd()
{
InitializeComponent();
}
public void SayHello()
{
MessageBox.Show("Hello World!");
// In reality, code that manipulates controls on the form
// would go here. So this method cannot simply be made static.
}
}
}
I am looking to be able to call SayHello()
from another form, simply by writing:
MainWnd.SayHello();
How could I accomplish this?
Upvotes: 4
Views: 9658
Reputation: 4914
You could probably find a way to make the main window a singleton, however that's not the best way to achieve the outcome you want, nor is it really an appropriate situation in which to use the singleton pattern.
If all of the other tool windows/ dialogs are encapsulated within the main window, then a much better pattern to use for communication would be events.
Have the inner windows/dialogs raise events to represent a 'request' for the main window to do something. Have the main window subscribe to these events, and do the work via the event handlers.
By avoiding the singleton approach, you avoid the difficulties of testing the singleton, as well as avoiding extensive explicit circular references, where not only does the main window have references to the encapsulated windows/dialogs, but they in turn have explicit references back to the main window.
Upvotes: 4
Reputation: 17680
See below.
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace MyLittleApp
{
public partial class MainWnd : Form
{
public static MainWnd Instance;
public MainWnd()
{
Instance = this;
InitializeComponent();
}
public void SayHello()
{
MessageBox.Show("Hello World!");
// In reality, code that manipulates controls on the form
// would go here. So this method cannot simply be made static.
}
}
}
You can now use it anywhere in your code by calling MainWnd.Instance
All its members are also available to the instance.
Upvotes: 1
Reputation: 30728
You can certainly do this.
public MainWnd Instance = new MainWnd();
Then access as MainWnd.Instance.SayHello()
.
Replace following calls
MainWind instance = new MainWnd();
To
MainWnd instance = MainWnd.Instance;
I am not sure how Visual Studio designer would react after making the constructor as private though. But if it does not allow, it will be Visual Studio issue, rather than language/compiler issue.
Upvotes: 0