stop executing code after new form is loaded - c#

Some method call this method which has this code:
Form frm = new Form();
frm.Show();
but i do not want to execute first method anymore after form is loaded. How can i prevent and stop loading code in forst form

Very unclear, I'm guessing that you want to make sure that only one instance of a form can be created. You do so by keeping track of the life of the instance. Like this:
private Form2 instance;
private void showForm2() {
if (instance == null) {
instance = new Form2();
instance.FormClosed += delegate { instance = null; };
instance.Show();
}
else {
instance.WindowState = FormWindowState.Normal;
instance.Focus();
}
}

Edit: question is very unclear so I give an answer based on my understanding of it...
to block execution after a form has been created, until such form is closed, try to use ShowDialog()
using(var frm = new Form1())
{
frm.ShowDialog();
// here your code is not executed until frm is closed...
//...
//...
}
Please pay attention that you do not want to create an object of type Form as that is the default base class and will not contain your controls...

Related

C# Using function from another file

Ok, so, I have functions.cs file where i stored following function
public static void Global_Reset()
{
Form1 blok = new Form1();
blok.userControl1.Visible = false;
blok.userControl2.Visible = false;
blok.userControl3.Visible = false;
if (Properties.Settings.Default.client == 1)
{
blok.userControl1.Visible = true;
MessageBox.Show("First");
}
else if (Properties.Settings.Default.client == 2)
{
blok.userControl2.Visible = true;
MessageBox.Show("Second");
}
else if (Properties.Settings.Default.client == 3)
{
blok.userControl2.Visible = true;
MessageBox.Show("Third");
}
else
{
MessageBox.Show("Error");
}
}
When I call fun.Global_Reset() in Form1 or in any user control that is used in Form1, visibility never changes but I got messages (First, Second, Third). Is there any way to solve this?
I tried to use this directly in Form1 and it used to work, but when I call it from userControl that was used in Form1 it's not working again.
This is the form you're modifying:
Form1 blok = new Form1();
It only exists during the scope of that method (function), and it is never shown to the user. It's not the form instance you're seeing on the screen.
As an analogy... Imagine the form you're seeing is a car. What you're doing is getting another car that looks just like it and putting something in the trunk of that car, then noticing that what you put in the trunk of the second car can't be found in the trunk of the first car.
Instead of creating a new form instance, pass the existing instance to this method:
public static void Global_Reset(Form1 blok)
{
// don't create an instance here, just use the blok that was passed
}
Then pass that instance from your form, for example:
fun.Global_Reset(this);

How to affect child form from parent form in mdi c#

My problem is that I have created child's object and show child first time. but when second time I just want to change value of child's label from parent but don't want to show another form.
Here is my code.
First time
ChildForm ObjChild = new ChildForm("Hi");
ObjChild.Show();
On second time I just want to set Bye in place of Hi.
ChildForm ObjChild = new ChildForm("H!");
ObjChild.BringToFront();
Because child form is already opened.
This is my child Form
public Form1(string p_Param)
{
InitializeComponent();
Label1.Text = p_Param;
}
Constructors call one time when object created. You must implement a new public void or function rather than a constructor to do that.
public void ChangeLabelText(string txt)
{
Label1.Text=txt;
}
EDIT:
In your parent form;
Out of functions;
chilFrm ChildForm;
Inside any function;
if (chilFrm == null)
{
chilFrm = new ChildForm();
chilFrm.TopLevel = false;
chilFrm.Parent = this;
chilFrm.StartUpProsecc("Created New");
chilFrm.Show();
}
else
{
chilFrm.StartUpProsecc("Showed the existing.");
chilFrm.BringToFront();
}

Pass in parent form to ShowDialog that is called from a class instance

I have a form.
In that form I create an instance of a class on a new thread because it runs some long running logic. The form also gives the user the ability to cancel this logic/thread.
That class opens a new form if input is required.
The new form sometimes appears behind the other form.
I set a property on the class:
public Form ParentForm{get;set;}
I can now do:
MyForm form = new MyForm();
form.ShowDialog(ParentForm);
However I get a cross thread exception when calling ShowDialog(ParentForm).
I know I can use InvokeRequired somehow but not sure how on a property.
Thanks
UPDATE: Have tried doing this but still get exception:
MyForm form = new MyForm();
form.ShowDialog(GetParentForm());
private Form GetParentForm()
{
//You have to Invoke() so you can wait for the function to return and obtain its return value.
if (ParentForm.InvokeRequired)
{
return (Form)ParentForm.Invoke(new Func<Form>(() => GetParentForm()));
}
else
{
return ParentForm;
}
}
Your updated method (GetParentForm) won't work because you're wrapping the task of getting the reference to ParentForm in an InvokeRequired block. You could try wrapping the ShowDialog call in such a block instead, but I think you would still get the cross-threading error.
Your simplest fix would be to move the code that creates and shows the second form out of your class and into ParentForm. So instead of this:
MyForm form = new MyForm();
form.ShowDialog(ParentForm);
you would do this:
ParentForm.showMyNewForm();
and in ParentForm you would have this:
public void showMyNewForm()
{
MyForm form = new MyForm();
form.ShowDialog(this);
}
If MyForm needs to have a reference to the class on the other thread, you would just add a parameter to showMyNewForm() so that the reference to it can be passed in.
What you're trying to do here (creating and showing related, connected forms that are created on different threads) is really going against the grain of how forms are meant to be used in .NET.
you can add async method to a form.
Let's say like this:
public class MyForm : Form
{
public void ShowModalAsync()
{
this.Invoke(new Action(()=> {
ShowDilaog(..);
}));
}
}
and use this, like:
MyForm form = new MyForm();
form.ShowModalAsync(...);
Should work for you.
By the way, if your problem is only the fact that the window appears on bihind of others, try to make use of Form.TopMost property setting it to true. Having in mind that it, yes, will bring it infront of other forms, but not necessary infront of other topmost forms.

c# Windows form application forms problem

I have a c# windows form app which contains several forms.
Generally, for example, in form1, I create a instance of form2 and then
form1.hide();
form2.show();
But sometimes I want the previous form to show and dispose current form. How can I call the previous form?
Thanks in advance.
To answer your question, you need to maintain references in your views to each other. While this might work it's messy and error prone. It sounds like all your control logic is probably contained within your form class code and I would suggest moving away from that and separate your concerns.
Solving your form management issues becomes very simple if you create a controller class that, at a minimum, manages the creation and disposal of your forms in whatever way you see fit.
So your code sample would actually be launched from a controller class as something like:
public class FormsController
{
private Form form1 = new Form();
private Form form2 = new Form();
public void SwitchForms()
{
form1.hide();
form2.show();
}
}
For further edification checkout the MVC architectural pattern for cleanly working with data, biz logic and UI.
You might consider extending Form to include some properties/fields that allow you to access other forms. the Form class can be inherited from just like most other .Net classes.
You may also consider doing some of that management in the Program.cs file that is part of you project, if neither form is really supposed to be a child of the other.
If you inherit a new class for your form1 from Form and add a method like closeSecondForm you can have it close and dispose the second form.
There are probably a bunch of different ways to solve the issue. These are just a few.
If you set the new form's Owner to a reference to the current form, you can reference that Owner from the new form. You could also subscribe to the new form's Closed() event from the old form, with code to dispose it (though the form can dispose itself by overriding OnClosed, if it doesn't happen there anyway).
This logic should be handled in Program.cs. The Main() method initializes Form1. You want to take control there instead of passing control to the form.
Example:
static class Program
{
internal static Form1 MyForm1;
internal static Form2 MyForm2;
///
/// The main entry point for the application.
///
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Application.Run(new Form1());
// Initialize Form1
MyForm1 = new Form1();
MyForm1.FormClosing += new FormClosingEventHandler(MyForm1_FormClosing);
// You may want to initialize Form2 on-demand instead of up front like here.
MyForm2 = new Form1();
MyForm2.FormClosing += new FormClosingEventHandler(MyForm2_FormClosing);
// Show Form1 first
MyForm1.Show();
// Now we need to occupy the thread so it won't exit the app. This is normally the job of Application.Run.
// An alternative to this is to have a third form you pass on control to.
while (true)
{
Application.DoEvents();
System.Threading.Thread.Sleep(10);
}
}
static void MyForm1_FormClosing(object sender, FormClosingEventArgs e)
{
// Do something, for example show Form2
MyForm2.Show();
// EXAMPLE: We only want to hide it?
e.Cancel = true;
MyForm1.Visible = false;
}
static void MyForm2_FormClosing(object sender, FormClosingEventArgs e)
{
// Do something, for example show Form1
MyForm1.Show();
// EXAMPLE: We only want to hide it?
e.Cancel = true;
MyForm2.Visible = false;
}
}
Since Program is static you can access MyForm1 and MyForm2 anywhere in that project by:
Program.MyForm1.Show();
Program.MyForm2.Hide();
If you plan to have many forms/complex logic I suggest moving this to a separate class. Also consider using a single form and rotate user controls inside it instead.
Form2 myform = new Form2();
myform.show();
this.hide();
You could do this in form1:
...
var form2 = new form2();
form2.Closing += (form2_Closing);
this.hide();
form2.show();
...
private void form2_Closing(object sender, System.EventArgs e)
{
this.show();
}

Single instance form but not singleton

I cannot understand how this is possible. Please help!!
I have an app with a trayicon. I want a form to be show when the user double clicks the trayicon. I have a problem where it is possible to get 2 or more forms showing by quickly triple or quadruple clicking the trayicon. The reason I don't want a singleton is that I want the form to be released each time it is closed to save memory, maybe this is not a good idea?
I have a field called m_form1.
I have a method called ShowForm1;
I call the method ShowForm1 on the double-click of the TrayIcon.
private Form1 m_form1;
private void ShowForm1()
{
if (m_form1 == null)
{
Trace.WriteLine("*CREATE*" + Thread.CurrentThread.ManagedThreadId.ToString());
m_form1 = new Form1();
m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
m_form1.Show();
}
m_form1.BringToFront();
m_form1.Activate();
}
So when Form1 takes a while to construct, then it is possible to create 2 because m_form1 is still null when the second call arrives. Locking does not seem to work as it is the same thread both calls (I'm guessing the UI thread) ie the trace writes out *CREATE*1 twice (below).
[3560] *CREATE*1
[3560] *CREATE*1
Changing the code to include a lock statement does not help me.
private Form1 m_form1;
private object m_Locker = new object();
private void ShowForm1()
{
lock (m_Locker)
{
if (m_form1 == null)
{
Trace.WriteLine("****CREATE****" + Thread.CurrentThread.ManagedThreadId.ToString());
m_form1 = new Form1();
m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
m_form1.Show();
}
}
m_form1.BringToFront();
m_form1.Activate();
}
How should I handle this situation?
Thanks guys
Tim.
Have an additional boolean variable, "m_formUnderConstruction" which you test for before constructing the form, and which you set as soon as you've decided to construct it.
The re-entrancy makes all of this a little icky, unfortunately. I've removed the lock, as if this ever gets called from a different thread then you've got the nasty situation of trying to show a form from a different thread to the one it was constructed on.
private Form1 m_form1;
private bool m_underConstruction = false;
private void ShowForm1()
{
if (m_underConstruction)
{
// We're about to show it anyway
return;
}
m_underConstruction = true;
try
{
if (m_form1 == null)
{
m_form1 = new Form1();
m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
m_form1.Show();
}
}
finally
{
m_underConstruction = false;
}
m_form1.BringToFront();
m_form1.Activate();
}
Use Interlocked.Increment to change the nr of the tries. If it is 1, open the form, otherwise, don't. And use Interlocked.Decrement after the test or on form's close.
private int openedForms = 0;
private Form1 m_form1;
private void ShowForm1()
{
if (Interlocked.Increment(ref openedForms) = 1)
{
m_form1 = new Form1();
m_form1.FormClosed += new FormClosedEventHandler(m_form1_FormClosed);
m_form1.Show();
}
else
{
Interlocked.Decrement(ref openedForms);
}
if (m_form1 != null)
{
m_form1.BringToFront();
m_form1.Activate();
}
}
private void m_form1_FormClosed(object Sender, EventArgs args)
{
Interlocked.Decrement(ref openedForms);
}
Please see this, it handles all mouse event combinations for NotifyIcon as well as Form1.
More here: http://code.msdn.microsoft.com/TheNotifyIconExample

Categories