Well normally I am quite good at figuring and researching problems without guidance however I have come across a snag. I am trying to create an "Event" with C# (which I have not done before) everything I have looked up has nothing to do with what I need.
I am trying to call a class on my main form when form2 is hidden. I found some code which was supposed to check to see if form2 closed - Either I didn't integrate it into my code properly or closing is different to hiding.
So just to clarify I want to run through the program like this:
Form1 runs
Click setting button on Form1 which opens Form2
Form2 opens where settings can be changed
Click the "Ok" button on Form2 (here is where I want Form1 to realise Form2 has been hidden
Hide form one and run a class called Refresh which refreshes button names and URLs
Also,
you can use VisibleChanged event in Form2
private Form2_VisibleChanged(object sender, EventArgs e)
{
if (!this.Visible) { Refresh(); }
}
This might be more elegant...
Open the second form as modal
Form2 form2 = new Form2();
DialogResult result = form2.ShowDialog();
check the result and refresh:
if (result == DialogResult.OK)
Refresh();
What you also need to do in this case is when closing the form set DialogResult of the form, for example if you have an OK button, in the button handler set:
this.DialogResult = DialogResult.OK;
This will automatically close the form as well as I remember correctly.
What you can also do is set DialogResult.Cancel on cancel button if you need that.
If I understand correctly, you want to have a class that stores settings information that both Form1 and Form2 can access. Let's call that class Form1Settings, and implement as:
public static class Form1Settings
{
public static string ButtonText;
public static string Uri;
}
For simplicity, I made this class and its properties static, so both Form1 and Form2 have direct access to it, removing the need for a refresh method.
Form1 would call Form2 in a blocking way, and only update its display if the OK button was clicked.
public partial class Form1 : Form
{
private Form2 form2 = new Form2();
public Form1()
{
InitializeComponent();
}
private void buttonSettings_Click(object sender, EventArgs e)
{
if (form2.ShowDialog() == DialogResult.OK)
{
this.button1.Text = Form1Settings.ButtonText;
this.textBoxUrl.Text = Form1Settings.Uri;
this.Update();
}
}
}
And finally, Form2 will update the settings values with input from the user:
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void buttonOK_Click(object sender, EventArgs e)
{
Form1Settings.ButtonText = this.textBoxButton.Text;
Form1Settings.Uri = this.textBoxUri.Text;
this.DialogResult = DialogResult.OK;
this.Hide();
}
}
Why not open Form2 as a modal dialog using ShowDialog()? That way you may return a value if Form2 was closed by OK or by Cancel and act accordingly in Form1 after the call returned.
Related
Is there a way I can call a function that is present in the parent form (users), where an instance of a second form(addNewUser) is called? What I want to do is when the second form closes, to execute a function in the parent form (users) which is updating a table so that the changes done in the second one (addNewUser) are updated in the table in the first form (users).
a simple drawing of what I am trying to achieve
With an event driven paradigm like WinForms the best path is to use the events when there is one that you can intercept.
You can subscribe to an event from any class that creates instances of the event raiser. In this case you could simply bind an event handler to the FormClosed event raised by the second form.
// Suppose you have a button click that opens the second form.
private void button_Click(object sender, EventArgs e)
{
SecondForm f = new SecondForm();
f.FormClosed += onSecondFormClosed;
f.ShowDialog();
}
private void onSecondFormClosed(object sender, FormClosedEventArgs e)
{
// Do whatever you need to do when the second form closes
}
Define global variables to identify your instances of your forms:
internal static Form1 CurrentForm1 { get; set; }
internal static Form2 Frm2 { get; set; }
Then affect the variables as follows:
public Form1()
{
InitializeComponent();
CurrentForm1 = this;
}
Somewhere in your code, you'll define the Form2:
Frm2 = new Form2();
Now, from the Frm2 code, you'll access to the form1 non static methods with:
Form1.CurrentForm1.UpdateMyThings();
And from the Frm1 code, you'll be able to watch the things on Frm2, like:
bool notified = false;
while (Frm2.backgroundWorker1.IsBusy)
{
if (notified == false)
{
Message("Please wait...");
notified = true;
}
Application.DoEvents();
}
In this example, Frm1 checks if the backgroundworker #1 is still running in Frm2 (The Message function may display the message in a label or something).
I have following problem:
I have a Form1 where I open a second Form2 from it. Now I have a save Button in Form2 where entries from Textboxes are saved to a csv file. But I want to save some entries from Form1 too. The Textbox entries from Form2 are getting saved but entries from Form1 are empty strings. Following code:
In Form1:
public void showInputToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2(this);
form2.Show();
}
to open the second Form via the first one and functions to grab the entries from the Form1 Textboxes:
public String getLocation()
{
return LocationBox.Text;
}
public String getFilesLoc()
{
return FilesLocation.Text;
}
In Form2 I have the following:
private Form1 m_form = null;
public Form2(Form1 f)
{
InitializeComponent();
m_form = f;
}
and then the function to grab the entries and save them:
private void button1_Click(object sender, EventArgs e)
{
Form1 form1 = new Form1();
proc.setParams(form1.getLocation(),getFilesLoc());
proc.saveCurrentSettings();
}
I left the other parameters out. So entries from Form2 are read correctly but the ones from Form1 are just an empty string (""). What can I do?
In the click handler, you're creating a new Form1 here:
Form1 form1 = new Form1();
That will have empty values - but you want the value from the existing form which you kept a reference to in your constructor - so use it!
private void button1_Click(object sender, EventArgs e)
{
proc.setParams(m_form.getLocation(), m_form.getFilesLoc());
proc.saveCurrentSettings();
}
(I'd strongly advise you to start following .NET naming conventions, quite possibly turning those get methods into properties, and also considering passing the values into your Form2 constructor instead of the Form1 reference itself. It depends on whether you need to "see" any changes made to Form1 after the construction of Form2.)
use
proc.setParams(m_form.getLocation(), m_form.getFilesLoc());
proc.saveCurrentSettings();
you are not using the reference of Form1 but creating a new object and using that.
I want that when I insert or update records in another form (Form2), the DataGridView on Form1 should automatically refresh (call btnRefresh) after each operation or preferably wait until all change operations have finished, and update the DataGridView form Form2's closing event with all changes.
I believe in VB.NET this is achieved with Form1.DataGridView.Refresh, but I am not sure in C#. I was told that I pass the reference of the DataGridView on Form1 to Form2 using properties but since I'm new to C#, I didn't know how to. How can I resolve this issue?
My refresh button code:
private void btnRefresh_Click(object sender, EventArgs e)
{
GVThesis.DataSource = thesisRepository.GetThesis();
GVThesis.Refresh();
}
Firs, wrap your refresh code into a method of its own, and call that from your click event handler method, like so:
private void btnRefresh_Click(object sender, EventArgs e)
{
this.RefreshData();
}
public void RefreshData()
{
GVThesis.DataSource = thesisRepository.GetThesis();
GVThesis.Refresh();
}
Then, asuming you are instantiating and launching the new form (Form2) from your Form1, simply go into the code of Form2 and create yourself a new constructor overload which will accept a reference to Form1, and store it in a private variable, like so:
public partial class Form2 : Form
{
private Form1 frm1;
public Form2()
{
InitializeComponent();
}
public Form2(Form1 otherForm)
{
InitializeComponent();
this.frm1 = otherForm;
}
}
Then you can call the "refresh" from anywhere you like in Form2 like so:
this.frm1.RefreshData();
EDIT:I created a small sample, I cannot upload it here...but here is a screenshot of both the program itself in VS, as well as a screenshot of the result of running it and performing the function...hopefully that will help.
The program (zoom your view if it appears too small)
The Result:
I have a combobox on form1 that I need to call on form2 to get the user selection. Can some one please give me an example on how to do this?
EDIT: Forgot to explain what Im trying to do. I have a readonly textbox....a user clicks edit to edit the text but I want the text they want/chose to edit to pop up right when form2 is called.
I have this code on form1
public string SelectedComboValue
{
get { return comboBox1.SelectedItem.ToString(); }
}
And this code on form 2
EDIT: Added Form1 form1 = null; BUT its still not returning the SelectedComboValue
public Form2(Form1 parentForm1) : this()
{
form1 = parentForm1;
}
But it gave me an error saying that form1 is not in this context
I suppose that Form1 is the parent of Form2, so when you create the Form2 you use code like this
Form2 f = new Form2(this);
then in the Form2 class you should have a declaration like this
Form1 _parentForm = null;
and in the Form2 constructor
public Form2(Form1 parentForm1)
{
_parentForm = parentForm1;
}
If this is true then you can call
_parentForm.SelectedComboValue ;
to get the result required
in c#
Form 2:
create a combobox here
public string strDecVal{
set{ combobox1.text = value; }
}
in Form 1:
for example you have a textbox and a button that will go to form2
put these code on your button
Form2 frmShow = new Form2(); //Calling the form2
frmShow.strDecVal = textbox1.text;
frmShow.ShowDialog;
In VB it is much more automated:
Form1:
textbox and button
in clicking the button in form1
put the code:
Form2.Show()
in Form2:
on the Load put this code:
ComboBox1.Text = Form1.TextBox1.Text
You can wrap the combobox an object of the ComboBox class like this:
internal static ComboBox CB=comboBox1;
Then you can call it in the other form, and access all of the methods and attributes of the ComboBox class. If you want to add items to that CB, you can do it easily as you do in the parent form. It doesn't matter if it's internal or static, it's just for the example.
in my menuStrip i have multiple forms,
So in 1 of them i want to be access only when use is pass from a login form i have create..
Lets say menustrip, menu is on form1, and the login form is Form2,
So how i am gonna comebine this to so menustrip form open when the user first pass the form2 login..
i am searching all day over the net i found only by passing a variable and then if its true the form1 is gonna pop-out but it didnt work well!
Somewhere you will need to have a static Boolean property telling you if the user is logged in.
public static class Config {
public static bool LoggedIn { get; private set; }
public static Login ()
{
var frm = new frmLogin();
if (frm.ShowDialog() == DialogResult.OK) {
LoggedIn = frm.LoggedIn;
}
}
}
In frmLogin have again a public, but this time non-static property LoggedIn, which you set true if username and password are OK.
Then, in the menustrip form enable or disable the menu items accordingly in the form Activated event handler:
private void Form1_Activated(object sender, EventArgs e)
{
myToolStripMenuItem.Enabled = Config.LoggedIn;
}
Well thinking I got it right "You want to have input in form 1 from form2or something like modify something in form1 from form2"
It may not be the best but works
Well the simplest solution that has helped me till now is that you
Make menuStrip modifier from properties to public
create an instance on Form1 in Form2
Modify menuStrip from Form2
for example we can have
Form2.cs
public partial class ViewCars : Form
{
Form1 mainForm;
public ViewCars (Form1 MainForm)
{
this.mainForm = MainForm;
}
}
private void LoginButton_Click(object sender, EventArgs e)
{
mainForm.menuStrip.Visible = false;
}
Now to when you make the instance of Form2 you need to have give parameter this
i.e
ViewCars view = new ViewCars(this);
view.Show();
This is not Limited to controls you can do anything with it
Good Luck