Been stuck for quite a while reading similar posts here, I did find a solution but it was in dummy code and I just don't know what I'm doing wrong.
I have 2 forms, when the main form loads up I want to hide it and show form2 (the login form)
code looks like this.
private void Form1_Load(object sender, EventArgs e)
{
login loginform = new login();
loginform.Show();
this.Hide();
}
But when I run the program both forms are open and visible.
What am I doing wrong? Shouldn't the main form be hidden?
The Hide method does not have any effect from the Load event, since there isn't a handle created yet.
You have two options:
Using the Shown event (or better, the HandleCreated event) and hide it if a condition is met (like a variable 'logon form not shown')
Show the logon form as start form, then open the 'main' form. You can do this by passing an ApplicationContext around and pass on control to the main form.
You can do it with help of owner property, here is working example
Main form
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
var loginFormMax = new LoginFormMax { Owner = this };//save main form as owner inside child form
loginFormMax.Show();
}
}
Child Form
public partial class LoginFormMax : Form
{
public LoginFormMax()
{
InitializeComponent();
}
private void LoginFormMax_Shown(object sender, EventArgs e)
{
var owner = this.Owner;
owner.Hide();//now you have control over owner form, just hide it
}
private void LoginFormMax_FormClosing(object sender, FormClosingEventArgs e)
{
var owner = this.Owner;
owner.Show();//now you have control over owner form, just show it again
}
}
Related
I want to click button and go to FormSetting, and close current FormMain. When I'm done working on FormSetting, I want to click the back button and go back to FormMain.
//FormSetting
private void ButtonSetting_Click(object sender, EventArgs e)
{
this.Hide();
FormSetting formsetting = new FormSetting();
formsetting.SetPrevForm(this);
// OpenSeconderyForm(formsetting);
formsetting.ShowDialog();
}
//FormMain
public void SetPrevForm(Form f)
{
formMain = f;
}
private void toolStripButton8_Click(object sender, EventArgs e)
{
this.Hide();
formMain.ShowDialog();
}
Your code has a main form and a settings form. When the settings form is shown, your code is attempting to hide the main form. When the Button8 on the ToolStrip in your settings form is clicked, your code tries to close the settings form and make the main form visible again. I will offer a few basics and you can modify them to your requirements. So let's start with minimal representations of your two forms:
Clicking the [Settings] button
The "trick" here is that when you call ShowDialog for your settings form, pass the this keyword. That will set the Owner property of your settings form to point to the main form.
public partial class MainForm : Form
{
public MainForm() => InitializeComponent();
private void buttonSettings_Click(object sender, EventArgs e)
{
_settings.ShowDialog(this);
}
SettingsForm _settings = new SettingsForm();
}
Hiding the main form when the settings is shown
By overriding the OnVisibleChanged method in your settings form, the visibility of the main form can now be manipulated using the Owner property. When Button8 is clicked, it closes the settings dialog which causes the Visible property to change to false. The OnVisibleChanged override will detect this so that the main form can be made visible again using the Owner property.
public partial class SettingsForm : Form
{
public SettingsForm() => InitializeComponent();
protected override void OnVisibleChanged(EventArgs e)
{
if(Visible)
{
Owner?.Hide();
}
else
{
Owner?.Show();
}
base.OnVisibleChanged(e);
}
private void toolStripButton8_Click(object sender, EventArgs e) => Close();
}
I hope the title is clear enough. Let me explain : I am doing a c# Winform App. When I start the app I have my Form 1 which starts, and I have other forms I can open from it by clicking buttons.
The problem is, I have functions in those Forms (Form 2, Form 3, Form 4..) I want to start from the Form 1 .
Currently here's my code
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
// First Event, when I click in the toolstrip menu, I open the Form2 ("Ligne3")
private void ligne3ToolStripMenuItem_Click(object sender, EventArgs e)
{
var Ligne3 = new Ligne3();
Ligne3.Show();
}
Then, I have components in the Form2 (textboxs, buttons, functions etc)
public partial class Ligne3 : Form
{
public Ligne3()
{
InitializeComponent();
}
private void Ligne3_Load(object sender, EventArgs e)
{
//Some code
}
}
//Function I want to call from the Form1
public void send_email()
{
//Some code
}
How can I start my " send_email() " function from the Form1 (for example during Load Event) ?
Assign the values of Form2 or any other objects/variables to Linge3 object before calling show. Values which are needed in send_email() to be assigned before calling send_email(). Something like below.
private void ligne3ToolStripMenuItem_Click(object sender, EventArgs e)
{
var ligne3 = new Ligne3();
//define variables/properties in Ligne3 for all values to be passed
//then assign them with corresponding values
ligne3.Value1 = objForm2.Value1;
ligne3.Value2 = objForm2.Value2;
ligne3.Value3 = objForm2.textBox1.Text;
ligne3.Value3 = objForm2.checkBox1.Value;
//and so on
ligne3.send_email();
ligne3.Show();
}
If you are clicking a buttons on Form1, to start and open forms 2,3,4 etc, and in those btn_click handlers you are creating a new form2, 3,3,4. Then you will have a reference to each form and and can therefore just call the respective public method on the instance just created. eg
public class Form1
{
private Form2 subForm2;
private void OpenForm2_Click(object sender, eventargs e)
{
subForm2 = new Form2();
subForm2.Show()
}
private void sendEmailBtn_Click(object sender, EventArgs e)
{
subForm2.Send_email();
}
}
This are many things wrong with the above from a design point of view but i'm just using it to present the idea.
If you are creating the instance of Form2,3,4 etc outside of Form1's instantiation, then you would need some form of Constructor or property injection to provide the instance references.
I have a main parent winform in which I have implemented some features and that have a number of child windows. Now I want the functionality I have implemented to run also on the child windows.
For instance, in the parent window I am moving an image on the selection of a checkbox. Now, if this checkbox is checked then the image should also move on the all other child windows.
Note: The image moving on the parent window should disapper and should only show on the opend dialogue or child window.
Please suggest if it is possible.
Try using events.
Create an event for the parent form called ImageMoved.
The child forms should subscribe to this event, and when you move the image, you raise the event, then the child forms will know to do their thing.
Lots of different ways to do this. Simple example:
public partial class Form1 : Form {
public event EventHandler ImageMoved;
private void OnImageMoved() {
if (ImageMoved != null)
ImageMoved(this, new EventArgs());
}
private void button1_Click(object sender, EventArgs e) {
OnImageMoved();
}
private void button2_Click(object sender, EventArgs e) {
Form2 f2 = new Form2(this);
f2.Show();
}
}
Then your child forms could look something like this:
public partial class Form2 : Form {
public Form2(Form1 parentForm) {
InitializeComponent();
parentForm.ImageMoved += new EventHandler(parentForm_ImageMoved);
}
void parentForm_ImageMoved(object sender, EventArgs e) {
MessageBox.Show("Image moved");
}
}
You could also create your own EventArgs class if you want to pass more information, such as which image, etc.
I want to run my form (with all controls disabled)
and over it there will be another form for username and password run as showDialog!
people will not be able to go to the main form without login!
private void Form1_Load(object sender, EventArgs e)
{
this.Show();
Form2 f2 = new Form2 ();
f2.ShowDialog();
}
I tried the code above and it dose not work as it should!
how I can achieve it the way I need?
cheers
From the parent form:
childForm.ShowDialog(this);
That will make the child form modal to the parent form. As far as the location goes, there is a property off of the form (that you will want to set on the child form) that tells it where to start (center screen, center parent, etc)
System.Windows.Forms.Form implements IWin32Window, this is why it works.
It isn't clear what the issue/question is, but you could try making sure you pass in the parent-form, i.e.
using(var childForm = new MySpecialLoginForm(...)) {
childForm.ShowDialog(this);
}
erm...
DialogResult result = mySecondForm.ShowDialog()
That will disable the parent form until this one is closed. DialogResult will be an enum value that is something like OK/Cancel/YesNo etc
I typically use the following pattern if I want to do sth. after the Form has fully loaded:
public partial class BaseForm : Form
{
public event EventHandler Loaded;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
Application.Idle += OnLoaded;
}
protected void OnLoaded(object sender, EventArgs e)
{
Application.Idle -= OnLoaded;
if (Loaded != null)
{
Loaded(sender, e);
}
}
}
If I derive my main form from BaseForm I have a Loaded event which, in your case, I would use as follows.
static class Program
{
[STAThread]
static void Main()
{
var mainForm = new MainForm();
mainForm.Loaded += (sender, e) => { new LoginDialog().ShowDialog(mainForm); };
Application.Run(mainForm);
}
}
I've a dgv on my main form, there is a button that opens up another form to insert some data into the datasource bounded to the dgv. I want when child form closes the dgv auto refresh. I tried to add this in child form closing event, but it doesn't refresh:
private void frmNew_FormClosing(object sender, FormClosingEventArgs e)
{
frmMain frmm = new frmMain();
frmm.itemCategoryBindingSource.EndEdit();
frmm.itemsTableAdapter.Fill(myDatabaseDataSet.Items);
frmm.dataGridView1.Refresh();
}
However, when I add this code in a button on the parent form, it actually does the trick:
this.itemCategoryBindingSource.EndEdit();
this.itemsTableAdapter.Fill(myDatabaseDataSet.Items);
this.dataGridView1.Refresh();
There are many ways to do this, but the following is the simpliest and it will do what you want and get you started.
Create a public method on your main form.
Modified constructor of second form to take a main form.
Create an instance of the second form passing the main form object.
When closing second form, call the public method of the main form object.
Form1
public partial class Form1 : Form {
public Form1() {
//'add a label and a buttom to form
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e) {
Form2 oForm = new Form2(this);
oForm.Show();
}
public void PerformRefresh() {
this.label1.Text = DateTime.Now.ToLongTimeString();
}
}
Form2
public class Form2 : Form {
Form1 _owner;
public Form2(Form1 owner) {
_owner = owner;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form2_FormClosing);
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e) {
_owner.PerformRefresh();
}
}
We can also proceed this way:
We have form_1 and form_2
In form_1, create a public method. Inside this public method we put our stuff;
In form_2 we create a global form variable;
Still in form_2, pass form_1 into form_2 through form_2 constructor;
Still in form_2, make your global variable(the one we created in step 2) receive the new form_1 instance we created in form_2 constructor;
Inside the closing_event method we call the method which contains our stuff.
The method with our stuff is the method that will fill our form1 list, dataGridView, comboBox or whatever we want.
Form_1:
public fillComboBox()//Step 1. This is the method with your stuff in Form1
{
foreach(var item in collection myInfo)
{myComboBox.Items.Add(item)}
}
Form_2:
Form1 instanceForm1;//Step 2
public Form2(Form1 theTransporter)//Step 3. This the Form2 contructor.
{
InitializeComponent();
instanceForm1 = theTransporter;//Step 4
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
instanceForm1.fillComboBox();//Step 5 we call the method to execute the task updating the form1
}
I hope it helps...
You're creating a new instance of the main form which isn't effecting the actual main form instance. What you need to do is, call the code on the main form itself, just like the code you say works on the button click:
private void frmNew_FormClosing(object sender, FormClosingEventArgs e)
{
this.itemCategoryBindingSource.EndEdit();
this.itemsTableAdapter.Fill(myDatabaseDataSet.Items);
this.dataGridView1.Refresh();
}
Great answer there! The other method would have been:
Check if the form you want to update is open.
Call the method to refresh your gridVieW.
**inside your refreshMethod() in form1 make sure you set the datasource to null **
if (System.Windows.Forms.Application.OpenForms["Form1"]!=null)
{
(System.Windows.Forms.Application.OpenForms["Form1"] as Form1).refreshGridView("");
}