When is a form displayed? - c#

I am trying to figure out when exactly the Form.Load event occurs. In MSDN it sais:
Occurs before a form is displayed for the first time.
But when the form is displayed for the first time? My first instinct was immediately after InitializeComponent(), but when I tried the following code, the MessageBox showed 5 even though the value was set after InitializeComponent(), so it's not immediately after InitializeComponent():
public partial class Form1 : Form
{
private int number;
public Form1()
{
InitializeComponent();
number = 5;
}
public void Form_Load(object sender, EventArgs e)
{
MessageBox.Show(number);
}
}
So When does it occurs?

OnLoad is one of the methods being called when you call Show or ShowDialog on a Form.
The first time you call Show or ShowDialog, OnLoad is called and your Load event is fired. (Just like OnHandleCreated, etc.)

Have a read of https://msdn.microsoft.com/en-us/library/86faxx0d(v=vs.110).aspx
This explains the order of startup and shutdown of forms.
In short, a number of events are triggered in order - eg create...load...activate..shown ..

Related

How to let an event in WinForms C# know the statements/declarations that are in the other events?

public partial class Form1 : Form
{ bool b=false;
private void button1_Click(object sender, EventArgs e)
{
b=true;
}
private void Form1_Load(object sender, EventArgs e)
{
if(b)
{
MessageBox.Show("hello");
}
}
}
What i mean is the if statement in Form1doesn't know that the boolean b is true when i click on the button1.
b stays false in Form1 because i declared it as that in the beginning before the events.
So how can i make Form1 here know that b is true when i click on button1?
Like how to connect/relate events?
In general how can i make the statements in an event know what happens in other events like here?
The Load event of a form is the first event to be raised in the form. And it is raised only once in each forms life time.
When a form is loaded, the stuff you declare between events and methods (in the body of your form) are created, then the constructor of the form is invoked (the one with InitializeComponent(); in it), and finally, the loaded event (if there is one) is raised.
Now, the default value of a Boolean variable is false (you've even set it to false manualy), so the button1_Click event which sets your boolean's value to true, will never be raised before the form's loaded event
Ergo what you want can't be achieved, unless, you store the boolean value to the database after each time the button is clicked, and read it from the database in the form upon loading.
I'd appreciate it if you accepted the answer, in case it helped clear things up.

What is the most elegant way to call an event of another Form?

Let's say I have a Form called Form1 which will somehow (how is not relevant) calls another form Form2
(Form1)
Form2 f2= new Form2();
f2.ShowDialog();
This Form2 has a button that will do some operation everytime the user clicks on this button.
However, I want that the first time i.e. when Form2 is just shown, the code in the button (some operation) gets executed.
In other words I have to be able to call the code in Form2's button_Click which is private.
Now I can think of some ways to make this possible(making the click event public etc) , but my question is what is the most elegant (or correct) way to do this?
I would add a property to Form2 to tell the form I like to automatically executed an action.
class Form2
{
public bool AutoExecuteSomeOperation { get; set; }
}
In Form1, you would set that property and in Form2 you would check and execute appropriate code if the property was set.
I would recommend that you refactor button_Click to call another method which you can also call for automatic execution. I like to keep event handler simple and executed only for the event on the control that served to name the event handler. Thus, you know that button_Click is an handler for a Click event on a control named button. It makes the code easier to maintain.
You can decide if you want to reset the property once the code is executed or you can add some validation that the property changes are valid. For exemple, you might want to ensure that the property is called before displaying the form.
In all cases, you should avoid having any reference to a control from an external form. Only Form1 itself should know that it contains a button. Any use from outside world should be done through a public property or public event of the form. That way, if you decide that the button should be replaced by an hyperlink, a menu item, a checkbox or anything else Form1 does not need to be updated. This is very similar to what should be done for UserControl. The less internal details leak, the easier it will be to make internal changes without having to update all caller.
The easiest approach is just make it public, however its not the bastion of great design.
Decoupled messaging is probably where you want to be, event aggregator or any pub sub method messaging system. This is a more modern and scalable approach, the participants need not know about each other allowing you to make the methods private and giving you a more maintainable decoupled solution, and keep your classes self consistent.
Unity, MvvmLight both have these sorts of messaging systems, however there are lots of them.
Example of how this might work
public Form1()
{
InitializeComponent();
EventPublisher.Instance.Subscribe<NewUserCreated>
(n => listBoxUsers.Items.Add(n.User.Name));
}
...
// some other class
private void Form2()
{
var user = new User()
{
Name = textBoxUserName.Text,
Password = textBoxPassword.Text,
Email = textBoxEmail.Text
};
EventPublisher.Instance.Publish(new NewUserRequested(user));
}
Move the code from the OnClick event into its own method (e.g. "DoWork"), then call that method from the OnClick event.
Either call it when you create the form
var frm = new demoForm();
frm.DoWork();
frm.Show();
Or call it in the forms constructor.
public partial class demoForm : Form {
public demoForm() {
InitializeComponent();
DoWork();
}
private void button1_Click(object sender, EventArgs e) {
DoWork();
}
public void DoWork() {
//Code here
}
}

Calling user created method in Form1 in Main()

I have a method in my Form1.cs called GenerateComboBoxList() and I want to call this in the main method so that the contents of the combo box is generated when the application is started.
public void GenerateComboBoxList()
{
cmbServerDatabase.Items.Add("1");
cmbServerDatabase.Items.Add("2");
cmbServerDatabase.Items.Add("3");
}
However, when I begin to type GenerateComboBoxList() in the main method, intellisense does not pick this up. Can anyone help with where I am going wrong?
You need an instance of the Form1 in your Main method, only then you can call your method, but, don't do that. Instead call this method in your Form_Load event or overload OnLoad (See: this).
Your Main method in Program.cs should only be responsible for specifying/loading the start up form. Later in your Form's Load event you can do:
private void Form1_Load(object sender, EventArgs e)
{
GenerateComboBoxList()
}
You can do it after InitializeComponents() in a constructor of your form :
public Form1()
{
InitializeComponents();
GenerateComboBoxList();
... other things that you want to set on startup
}
P.S. other option that is already suggested by people here would be to use an Form_Load event handler.

C# - Method is not being called upon .Load or .Shown [duplicate]

I have a Windows Forms form where I am trying to show a user control when the form loads. Unfortunately, it is not showing anything. What am I doing wrong? Please see the code below:
AdministrationView wel = new AdministrationView();
public ProgramViwer()
{
InitializeComponent();
}
private void ProgramViwer_Load(object sender, System.EventArgs e)
{
formPanel.Controls.Clear();
formPanel.Controls.Add(wel);
}
Please note I added the load event based on what I read in this article:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.load.aspx
Three ways you can do this - from the form designer, select the form, and where you normally see the list of properties, just above it there should be a little lightning symbol - this shows you all the events of the form. Find the form load event in the list, and you should be able to pick ProgramViwer_Load from the dropdown.
A second way to do it is programmatically - somewhere (constructor maybe) you'd need to add it, something like: ProgramViwer.Load += new EventHandler(ProgramViwer_Load);
A third way using the designer (probably the quickest) - when you create a new form, double click on the middle of it on it in design mode. It'll create a Form load event for you, hook it in, and take you to the event handler code. Then you can just add your two lines and you're good to go!
You got half of the answer! Now that you created the event handler, you need to hook it to the form so that it actually gets called when the form is loading. You can achieve that by doing the following:
public class ProgramViwer : Form{
public ProgramViwer()
{
InitializeComponent();
Load += new EventHandler(ProgramViwer_Load);
}
private void ProgramViwer_Load(object sender, System.EventArgs e)
{
formPanel.Controls.Clear();
formPanel.Controls.Add(wel);
}
}

How to add a form load event (currently not working)

I have a Windows Forms form where I am trying to show a user control when the form loads. Unfortunately, it is not showing anything. What am I doing wrong? Please see the code below:
AdministrationView wel = new AdministrationView();
public ProgramViwer()
{
InitializeComponent();
}
private void ProgramViwer_Load(object sender, System.EventArgs e)
{
formPanel.Controls.Clear();
formPanel.Controls.Add(wel);
}
Please note I added the load event based on what I read in this article:
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.load.aspx
Three ways you can do this - from the form designer, select the form, and where you normally see the list of properties, just above it there should be a little lightning symbol - this shows you all the events of the form. Find the form load event in the list, and you should be able to pick ProgramViwer_Load from the dropdown.
A second way to do it is programmatically - somewhere (constructor maybe) you'd need to add it, something like: ProgramViwer.Load += new EventHandler(ProgramViwer_Load);
A third way using the designer (probably the quickest) - when you create a new form, double click on the middle of it on it in design mode. It'll create a Form load event for you, hook it in, and take you to the event handler code. Then you can just add your two lines and you're good to go!
You got half of the answer! Now that you created the event handler, you need to hook it to the form so that it actually gets called when the form is loading. You can achieve that by doing the following:
public class ProgramViwer : Form{
public ProgramViwer()
{
InitializeComponent();
Load += new EventHandler(ProgramViwer_Load);
}
private void ProgramViwer_Load(object sender, System.EventArgs e)
{
formPanel.Controls.Clear();
formPanel.Controls.Add(wel);
}
}

Categories