C# WinForms. Enable control from another class - c#

In my program, I have two forms: public partial class Form1 : Form,
and a log-in form: public partial class Login : Form. Both within the same namespace
Login window is opened when a Log-in button is clicked on the main window:
public partial class Form1 : Form
{
private void LoginToolStripMenuItem_Click(object sender, EventArgs e) //Login button event
{
LoginWindow = new Login();
LoginWindow.ShowDialog();
LogOutToolStripMenuItem.Enabled = true;
}
}
When the password is entered, I want to enable additional controls for the user, on the main screen.
groupBox2 is invisible by default, now I would like to make it visible:
public partial class Login : Form
{
public Login()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e) //Confirm click event
{
if (textBox1.Text == Form1.password) //Here, no trouble accessing a string from the main screen
{
Form1.groupBox2.Visible = true; //********** Here is my problem **********
Form1.LoginWindow.Close();
}
else
{
textBox1.Text = "Incorrect password";
textBox1.SelectAll();
}
}
}
How do I overcome "An object reference is required for the non-static field, method or property 'Form1.groupBox2' problem?
All my controls are already set to public.
I'm reading and reading and can't figure it out, it's driving me mad now.
I'm not expecting a ready solution, just a good explanation.

You can just raise a event on your login form like this:
public partial class Login : Form
{
public EventHandler OnPasswordDone; // declare a event handler
public Login()
{
InitializeComponent();
}
public void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == Form1.password)
{
// raise the event to notify main form
OnPasswordDone(this, new EventArgs());
}
else
{
textBox1.Text = "Incorrect password";
textBox1.SelectAll();
}
}
}
And in your main form:
public partial class Form1 : Form
{
private void LoginToolStripMenuItem_Click(object sender, EventArgs e) //Login button event
{
LoginWindow = new Login();
LoginWindow.OnPasswordDone += Login_PasswordDone; // regist your event here
LoginWindow.ShowDialog();
LogOutToolStripMenuItem.Enabled = true;
}
private void Login_PasswordDone(object sender, EventArgs e)
{
//Do what you need to do here like:
groupBox2.Visible = true;
}
}

Since Form1 is not static class , so you should create object of this class then set visible to true like as
Form1 formobj=new Form1();
formobj.groupBox2.Visible = true;

Related

How do i create an event in a mdi parent form and catch it in a child form

I've found a fair amount of information on this subject and stolen most of my current code from other threads on this forum but don't seem to be able to put it all together correctly. I've created a main form "Form1" that is a mdi container. I can create a child form "formStripChart" from a menu item on Form1. I'd like to fire my own event that gets fired every time a timer_tick handler fires in Form1 and catch my event in an event hander in formStripChart to update a chart control. I can see that Form1 is calling the "UpdateStatus" method but OnUpdateStatus is always null so the "UpdateStatus" event handler in formStripChart never gets called. Seems like I'm not doing whatever needs to be done in formStripChart to make Form1 realize someone is listening to the event but I haven't been able to figure out what.
Here's the relevant code in Form 1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public delegate void StatusUpdateHandler(object sender, ProgressEventArgs e);
public event StatusUpdateHandler OnUpdateStatus;
private static double depthValue = 0.0;
private static Random randomValue = new Random();
private void timerData_Tick(object sender, EventArgs e)
{
depthValue = depthValue + randomValue.NextDouble() - 0.5;
iusblEventArgs.xValue = 0.0;
iusblEventArgs.yValue = 0.0;
iusblEventArgs.zValue = depthValue;
iusblEventArgs.timeStamp = DateTime.Now;
ProgressEventArgs args = new ProgressEventArgs("test status");
UpdateStatus("sent from timerData_tick");
}
private void UpdateStatus(string status)
{
// Make sure someone is listening to event
if (OnUpdateStatus == null) return;
ProgressEventArgs args = new ProgressEventArgs(status);
OnUpdateStatus(this, args);
}
public class ProgressEventArgs : EventArgs
{
public string Status { get; private set; }
public ProgressEventArgs(string status)
{
Status = status;
}
}
private void btnGo_Click(object sender, EventArgs e)
{
timerData.Enabled = true;
}
and here's the relevant code in formStripChart
public partial class FormStripChart : Form
{
private Form1 form1;
public FormStripChart()
{
InitializeComponent();
form1 = new Form1();
form1.OnUpdateStatus += new Form1.StatusUpdateHandler(UpdateStatus);
}
private void UpdateStatus(object sender, Form1.ProgressEventArgs e)
{
Console.Write("Update the chart here");
}
}
Thanks for any help.
It might be easier to pass form1 to the constructor of your child form like this:
Public void FormStripChart(Form1 f)
{
form1 = f;
form1.OnUpdateStatus += new Form1.StatusUpdateHandler(UpdateStatus);
}
This way your child form knows what instance of the main form to use.

I can not call my new form in my program after i created it

I have no idea about how this error was made. Here's my code and error.
I created a new form in solution explorer and wrote these codes in my main form. I'm sure that the hitbox which I used below is right.
public partial class HomePageForm : Form
{
OptionsPageForm frmOptions;
}
private void HomePageForm_MouseClick(object sender, MouseEventArgs e)
{
if (this.homePageOptionsButtonHitBox.Contains(e.Location))
{
this.Enabled = false;
frmOptions = new OptionsPageForm(this);
frmOptions.Show();
}
}
And these are codes i wrote in my "frmOptions" - which is the form i want to call.
public partial class OptionsPageForm : Form
{
OptionsPageForm frmHomePage;
public OptionsPageForm(HomePageForm frmCreator)
{
InitializeComponent();
frmHomePage =frmCreator;
}
}
The error given by visual studio is:
Cannot implicitly convert type "My Application_.MainPageForm" to "My Application_.OptionsPageForm".
And this is another form-calling I did in this application, it has the same structure as my call to frmOptionsPage, but it works perfectly.
public partial class HomePageForm : Form
{
GamePageForm frmGame;
}
private void HomePageForm_MouseClick(object sender, MouseEventArgs e)
{
if (this.homePageStartButtonHitBox.Contains(e.Location))
{
this.Hide();
frmGame = new GamePageForm(this);
frmGame.Show();
}
}
(In Gamepage form)
public partial class GamePageForm : Form
{
HomePageForm frmHomePage;
public GamePageForm(HomePageForm frmCreator)
{
InitializeComponent();
frmHomePage = frmCreator;
}
}
I now really want to get some help, please.
I think you need to move you Mouse Click event handler into the class like this
public partial class HomePageForm : Form
{
GamePageForm frmGame;
private void HomePageForm_MouseClick(object sender, MouseEventArgs e)
{
if (this.homePageStartButtonHitBox.Contains(e.Location))
{
this.Hide();
frmGame = new GamePageForm(this);
frmGame.Show();
}
}
}

Get data from Form 2 To Form1 And close

I have this class
Account.cs
namespace EasyFtp
{
class Account
{
public String Username;
public String Password;
public String FtpServer;
}
}
and i have MainWindow Form (Main window for my application ) and logForm with 3 textbox and button. I want to log to my ftp server before show my mainwindow , so i have to showdialog my logform and when thus user press button it get all information from logform and pass it to my mainwindow and save data in object of Account class ; my question is how i pass the data.
MainWindow.cs
namespace EasyFtp
{
public partial class MainWindow: Form
{
private Account myaccount;
LogInForm g;
public MainWindow()
{
InitializeComponent();
g = new LogInForm();
g.ShowDialog();
}
/* how i continue the code */
}
}
LogInForm
namespace EasyFtp
{
public partial class LogInForm : Form
{
public LogInForm()
{
InitializeComponent();
}
private void OKButton_Click(object sender, EventArgs e)
{
/*log in code (not created yet)*/
this.Dispose();
}
}
}
Update:
Your Main window
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
textBox1.Text = "original text";
}
private void button1_Click(object sender, EventArgs e)
{
new Form2().ShowDialog();
}
}
Your dialog-form, that will change the values in Form1
public Form2()
{
InitializeComponent();
// Get the text from Form1
textBoxOrg.Text = Application.OpenForms["Form1"].Controls["textBox1"].Text;
}
private void button1_Click(object sender, EventArgs e)
{
// Change the text on Form1
Application.OpenForms["Form1"].Controls["textBox1"].Text = textBox1.Text;
}
You probably wan't to change value on public properties instead of UI-elements.
Another, and cleaner way, is to pass fields to the form with a ref

hide main form, start new form, switch between the two without closing second form

I've got two forms, with subForm being called/created by a buttonClick in Form1. Right now I can initiate subForm, hide Form1, and then unhide Form1 when subForm is closed. What I'd like to be able to do is:
If user clicks changeform button, check to see if subForm is active but hidden
If no, then initiate subForm, else hide Form1, unhide subForm and pass control to it
If user clicks subForm's changeform button, hide subForm, unhide Form1 and pass control to it
If user clicks the "X" in the upper right corner of the form, then close the application, regardless of which form is active. (Right now, selecting the "X" closes the subForm and opens/unhides Form1.)
I can find solutions that do part of the requirements (and maybe all, I'm just too noob to know). To repeat from my previous question here, the code I have so far is:
Form1
private void countClick(object sender, EventArgs e)
{
this.Hide();
subForm myNewForm = new subForm();
myNewForm.ShowDialog();
this.Show();
countSelect.Checked = false;
}
and subForm
private void totalClick(object sender, EventArgs e)
{
this.Close();
}
This works, but it's not really elegant.
I think the best way to do this is to roll your own ApplicationContext. This allows you full control over the application lifetime without having it being tied to a specific Window. See http://msdn.microsoft.com/en-us/library/ms157901.aspx for more information.
Here's an example:
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyApplicationContext());
}
}
public class MyApplicationContext : ApplicationContext
{
public MyApplicationContext()
{
ShowForm1();
}
public void ShowForm1()
{
if (_form2 != null)
_form2.Hide();
if (_form1 == null)
{
_form1 = new Form1(this);
_form1.FormClosed += OnFormClosed;
}
_form1.Show();
MainForm = _form1;
}
public void ShowForm2()
{
if (_form1 != null)
_form1.Hide();
if (_form2 == null)
{
_form2 = new Form2(this);
_form2.FormClosed += OnFormClosed;
}
_form2.Show();
MainForm = _form2;
}
private void OnFormClosed(object sender, FormClosedEventArgs e)
{
if (_form1 != null)
{
_form1.Dispose();
_form1 = null;
}
if (_form2 != null)
{
_form2.Dispose();
_form2 = null;
}
ExitThread();
}
private Form1 _form1;
private Form2 _form2;
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public Form1(MyApplicationContext context)
: this()
{
_context = context;
}
private void button1_Click(object sender, EventArgs e)
{
if (_context != null)
_context.ShowForm2();
}
private readonly MyApplicationContext _context;
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public Form2(MyApplicationContext context)
: this()
{
_context = context;
}
private void button1_Click(object sender, EventArgs e)
{
if (_context != null)
_context.ShowForm1();
}
private readonly MyApplicationContext _context;
}
So we'll start out by going to the child form and creating a new event that can be used to notify the parent when it wants to change forms:
public event Action ChangeForm;
Then we fire the event and hide the child form when it wants to change forms:
private void ChangeForm_Click(object sender, EventArgs e)
{
Hide();
if (ChangeForm != null)
ChangeForm();
}
The parent form needs an instance of the child form as an instance field:
private subForm child = new subForm();
And it needs to initialize it in it's constructor, both adding handlers to the ChangeForm event to show the parent, and to the closed event to close itself:
public Form1()
{
InitializeComponent();
child.ChangeForm += () => Show();
child.FormClosed += (s, args) => Close();
}
Then all that's left is for the parent form to hide itself and show the child when it wants to change forms:
private void ChangeForm_Click(object sender, EventArgs e)
{
Hide();
child.Show();
}
Why not simply setting them to foreground, topmost, and so on ?
And setting them back vice versa ?
---added as comment as proposed
To access MainForm fromsubForm:
Create a constructor in your subForm and a field:
MainForm MainFormRef_Field;
subForm(MainForm MainFormRef)
{
this.MainFormRef_Field = MainFormRef;
}
Now you can access your MainForm using this reference. Like this:
MainFormRef_Field.Show();
MainFormRef_Field.Hide(); //or how ever you want to handle it
To access subForm fromMainForm:
To handle your subForm use the object you created for it. Here:
subForm myNewForm = new subForm();
To close whole application if any of the form closes:
Set a Form_Closing event for both forms:
private void MainForm_Closing(object sender, EventArgs e)
{
Application.Exit();
}
private void subForm_Closing(object sender, EventArgs e)
{
Application.Exit();
}
Note:
I am not writing the whole code for all of your cases. Set the variables, check the conditions. Its all up to you that how code it. All the main points you needed I've provided you the solution of them.

Enter Data to main form

I Made an application. The Main form Name is Form1.
And the other Form is called PoP.
public partial class pops : Form
{
public pops()
{
InitializeComponent();
CenterToScreen();
}
private void pops_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
Close();
}
private void lblAdminNo_Click(object sender, EventArgs e)
{
}
}
Make two public properties on popup form and retrieve them from parent form.
string username = string.Empty;
string password = string.Empty;
using (LoginForm form = new LoginForm ())
{
DialogResult result = form.ShowDialog();
if (result == DialogResult.Ok)
{
username = form.Username;
password = form.Password;
}
}
It all depends on from where are you calling the Pop form.
If it is called from the Form1 itself, then the Popform's object itself would provide you the value.
Pop popFrm = new Pop();
if(popFrm.ShowDialog() == Ok)
{
string userName = popFrm.TextBox1.Text;
}
If the Pop is invoked from a different area/part of application, you may have to store it somewhere common to both the forms.
This can be done through events. This approach is particularly useful when data to be posted even when the child form is kept open.
The technique is- From parent form, subscribe to a child from event. Fire the event when child form closes, to send data
----- SAMPLE CODE-----
Note: In the Parent Form add a Button:button1
namespace WindowsFormsApplication2
{
public delegate void PopSaveClickedHandler(String text);
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Pops p = new Pops();
p.PopSaveClicked += new PopSaveClickedHandler(p_PopSaveClicked);//Subscribe
p.ShowDialog();
}
void p_PopSaveClicked(string text)
{
this.Text = text;//you have the value in parent form now, use it appropriately here.
}
}
Note: In the Pops Form add a TextBox:txtUserName and a Button:btnSave
namespace WindowsFormsApplication2
{
public partial class Pops : Form
{
public event PopSaveClickedHandler PopSaveClicked;
public Pops()
{
InitializeComponent();
}
private void btnSave_Click(object sender, EventArgs e)
{
if(PopSaveClicked!=null)
{
this.PopSaveClicked(txtUserName.Text);
}
}
}
}
Summary:
1.Add a delegate(place where it available to both parent and child form) :
public delegate void PopSaveClickedHandler(String text);
2.In form:Pops, Add an event:
public event PopSaveClickedHandler PopSaveClicked;
3.Subscribe to the event in Parent Form:
p.PopSaveClicked += new PopSaveClickedHandler(p_PopSaveClicked);
4.Invoke the event in form:Pops Save Button Click
if(PopSaveClicked!=null)
{
this.PopSaveClicked(txtUserName.Text);
}
You can send data to the form object before you display it. Create a method to call, send the info through the constructor... etc.

Categories