|
samskiter wrote: I have declared my form as a class member variable ... because i want to only be able to show it once
IMO that does not make sense. Now each of the methods in that class could show the Form over and over again.
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
modified on Sunday, June 12, 2011 8:26 AM
|
|
|
|
|
its just the advise i got, have a look at my other thread...
|
|
|
|
|
Hi,
I did not read through that entire thread, probably the advice you got is correct, but the reason you mentioned does not fit.
My advice to you is make sure you understand why something does not work, and why the fix does work, don't just try different things until one of them works.
Luc Pattyn [Forum Guidelines] [My Articles]
- before you ask a question here, search CodeProject, then Google
- the quality and detail of your question reflects on the effectiveness of the help you are likely to get
- use the code block button (PRE tags) to preserve formatting when showing multi-line code snippets
modified on Sunday, June 12, 2011 8:26 AM
|
|
|
|
|
hmmm, well i didnt know u could use the "new" command outside of a method, i think i do understand the solution u gave now. is there any other way of making a new instance of the form only within my method, but that can only be opened once? at the minute all my method does is show the form, to me this seems to make the application more bloated (ie always having the form there, just showing and hiding it) i can tell its there cos the form itself has a notifyicon in it, and as soon as i start debugging it appears in the tray area.
|
|
|
|
|
You could make the form a Singleton (Google for it), so there's only ever one instance of it but it's not created until it's first needed.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
thanks, i had a look, seems like its just code to check if one already exists. and so i may aswell just put a check in my method that starts the form:
try
{
this.setting.Activate();
}
catch
{
this.setting = new Settings();
this.setting.Show();
}
i think i will stick with this code, i was just thinking there was some way of declaring/calling my form that would do this for me. thanks anyway guys
|
|
|
|
|
try / catch can get expensive... but if you're happy with it
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
lol fair enough... ill have a proper look through the singleton stuff later and have a go...
|
|
|
|
|
It's dead easy really.
public sealed class SingletonForm : Form
{
SingletonForm() { }
public static SingletonForm Instance
{
get { return Nested.instance; }
}
private class Nested
{
static Nested() { }
internal static readonly SingletonForm instance = new SingletonForm();
}
} Now when ever you need the form, just use SingletonForm.Instance followed by whatever property/method etc you want. It will always be the same form but it won't be instanciated until you first reference it, and it's thread safe.
Based on the samples (the last one) here[^].
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
ok brill,
that was pretty easy to use, fine with Show() but i get an error with ShowDialog(): "Form that is already visible cannot be displayed as a modal dialog box. Set the form's visible property to false before calling showDialog." id like to use showdialog as it lets me handle setting changes better when the form closes.
heres what i did in my form:
public partial class Settings : Form<br />
{<br />
public Settings()<br />
{<br />
InitializeComponent();<br />
}<br />
public static Settings Instance<br />
{<br />
get { return Nested.instance; }<br />
}<br />
private class Nested<br />
{<br />
static Nested() { }<br />
internal static readonly Settings instance = new Settings();<br />
}<br />
}
|
|
|
|
|
This works perfectly for me
public sealed partial class Settings : Form
{
private Settings()
{
InitializeComponent();
}
public static Settings Instance
{
get { return Nested.instance; }
}
private class Nested
{
static Nested() { }
internal static readonly Settings instance = new Settings();
}
} No problems with ShowDialog or anything else at all.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
weird it was only if i ran ShowDialog() twice that it did it BTW
heres the method:
public void COMMenuItem_Click(object sender, EventArgs e)
{
Settings.Instance.ShowDialog();
}
first time, it shows fine, but second time this is ran, i get the error.
this is supposed to work without a try...catch right?
|
|
|
|
|
Yeah, no need for try catch. I called Settings.Instance.ShowDialog(); twice in succession and it was no problem. ShowDialog returns with the form's visible state to false so it's not possible.
The only way that can happen is if the method that uses the ShowDialog is being called asynchronously from another thread, or if Show() has previously been used and the form wasn't closed, or the Settings form tries to show itself whilst already visible.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
im not too sure whats going on with it then.
the showdialog() is ran whenever i click a button in a right click menu of an icon... i think the event is allowed to be called even when the form is already there, so perhaps the problem is here:
ToolStripMenuItem COMMenuItem = new ToolStripMenuItem("COM Port", null, new EventHandler(COMMenuItem_Click));
|
|
|
|
|
samskiter wrote: is allowed to be called even when the form is already there
Yeah, that's your problem.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
so making a it a singleton wont work?
|
|
|
|
|
A singleton fulfils you original objective of only having one instance of the form and it not being instanciated right at the start of your application.
If you're trying to show the same instance again before the first one is closed then you've got some serious problems elsewhere in your code that need rethinking.
Using a try...catch to solve a bad coding issue is no real solution. Identify and fix the problem.
Are you trying to show the dialog again from itself? If not, how can anything else (menus or otherwise) be accessible? The dialog form will block until closed.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
Where is this menu - is it a context menu on a NotifyIcon?
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
yes, its a notifyicon
it is defined in the Main() of my program:
public void OldMain()
{
if (SerPort.OpenPort())
{
icn = new NotifyIcon();
ContextMenuStrip menu = new ContextMenuStrip();
icn.ContextMenuStrip = menu;
ToolStripMenuItem COMMenuItem = new ToolStripMenuItem("COM Port", null, new EventHandler(this.COMMenuItem_Click));
ToolStripMenuItem ExitMenuItem = new ToolStripMenuItem("Exit", null, new EventHandler(ExitMenuItem_Click));
ToolStripSeparator separator = new ToolStripSeparator();
menu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { COMMenuItem, separator, ExitMenuItem });
icn.Visible = true;
icn.Icon = Properties.Resources.ehshell_IDI_APP1;
icn.ShowBalloonTip(3000, "Connected", "Duke Box is Connected", ToolTipIcon.Info);
MediaCenterController MCC = new MediaCenterController();
MCC.MediaStateChange += new MediaCenterController.MediaCenterHandler(SerPort.MediaCenter_Running);
MCC.MediaStateChange += new MediaCenterController.MediaCenterHandler(MediaCenter_Running);
Thread trd = new Thread(new ThreadStart(MCC.MediaCenterRunning));
trd.IsBackground = true;
trd.Start();
Application.Run();
}
else
{
}
}
i have checked the thread is not causing the problem, there is not way for the event to be fired from the thread...
|
|
|
|
|
samskiter wrote: yes, its a notifyicon
... now it makes sense!
No need to try/catch, just disable the menu item in the click handler before the ShowDialog and enable it again afterwards.
private void COMMenuItem_Click(object sender, EventArgs e)
{
COMMenuItem.Enabled = false;
Settings.ShowDialog();
COMMenuItem.Enabled = true;
}
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
BAGH! more of the same; despite declaring like this: public ToolStripMenuItem COMMenuItem;
im getting another "Object reference not set to an instance of an object." error when i click the button!
i quite like the behaviour of the properties window of the system clock (right click the clock and click properties twice)...
|
|
|
|
|
That line of code doesn't create an instance of a ToolStripMenuItem. It needs to be:
public ToolStripMenuItem COMMenuItem = new ToolStripMenuItem();
That's not done with ShowDialog. It's a normal Show() and it just checks to see if it's already visible. If not, it shows it. if it is, it justs focuses it.
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
DaveyM69 wrote: That line of code doesn't create an instance of a ToolStripMenuItem
sorry, i thought the instance created in my OldMain method would be public and so would work... i tried what you suggested with showdialog before and got another error, but with show its alright.
just a couple more things:
1. it doesnt give focus, is this something i should include int he singleton code
2. upon closing and reopening the form, i get an error "Cannot access a disposed object." i think this is part of the forms coding, to dispose itself when it is closed? when i was using try...catch, i had to include a couple of lines after showdialog:
setting.Dispose();
setting = null;
i believe this is the solution so im trying to do that with Settings.Instance, but its throwing up an error about being read only. so, after removing the = null; line it ran, but the form would close straight away, which has led me to realise that...
because i am using Show, disabling the button isn't working as the button is re-enabled straight away! so im still getting the same error if i try and open the form twice!
|
|
|
|
|
Yeah, using show the form will close and dispose when closed. You can catch the FormClosing event from the main program and cancel the close but hide instead.
void Instance_FormClosing(object sender, FormClosingEventArgs e)
{
if (!Disposing)
{
e.Cancel = true;
Settings.Instance.Hide();
}
}
private void COMMenuItem_Click(object sender, EventArgs e)
{
if (Settings.Instance.Visible)
Settings.Instance.Focus();
else
Settings.Instance.Show();
}
DaveBTW, in software, hope and pray is not a viable strategy. (Luc Pattyn)Visual Basic is not used by normal people so we're not covering it here. (Uncyclopedia)
|
|
|
|
|
ok, but doesnt hiding it mean that once created the form will always exist?
|
|
|
|