Accessing controls on a new form - c#

I have 2 forms in my project, form1 and form2. When I click in a button in form1 I run this code:
Form tempform = new Form2();
tempform.Show();
In my code for Form2 I have a label which I now need to change the text.
How can I access the label?
I tried:
tempform.label1.value = "new text"
And that didn't work, I even tried to access using the Controls collection but I think I messed that up. Is there any way I can access the label? OR is there any way I can pass a value to that new form and then have that form alter the label text.
Thanks

If the label value should only be set once, when the form is created, then use a constructor for Form2 like this:
public Form2(string labelValue)
{
_labelValue = labelValue;
}
and then call that constructor when you create the form.
Alternatively, if the label changes over the lifetime of the form, make a public property:
public string LabelValue
{
get { return label1.Text; }
set { label1.Text = value; }
}
Also I would recommend naming the parameters and/or properties to reflect the meaning of the value, for example "titleText" instead of "labelValue". That way Form2 can decide how it wants to display the information (in the title bar, a label, a textbox, etc), and Form1 doesn't have to worry about that.
Edit: Consume the LabelValue property like this:
Form2 newForm = new Form2(); // Assign object to a Form2 instead of Form
newForm.LabelValue = "new text";
newForm.Show();

Controls have protected access by default. You can change that to public, or you can add a method/property to your form2 class to set the label and call that (latter method is generally preferred to preserve encapsulation and because the designer may want to overwrite your public change.).

Related

How can I programmatically make a control added to a form, public?

For exampple
Form1 frm1 = new Form1();
TextBox tb = new TextBox();
frm1.Controls.Add(tb);
now I can't say frm1.tb because tb is not public.
If i'd drawn the textbox then I could go to the properties window and set the modifier to public. So, I know how to do it in the GUI.
But how can I do it programmatically?
Added Clarification
Some have suggested alternatives to frm.tb, that wasn't what I was looking for.
I'll elaborate.
Consider this winforms program. It has two forms. Form1 and FormX
This is FormX
Form1 has just this code in its load
FormX frmx = new FormX();
frmx.drawnTextBox.Text = "blah"; //works
TextBox programmaticallyMadeTextbox = new TextBox();
frmx.Controls.Add(programmaticallyMadeTextbox);
frmx.Show();
frmx.programmaticallyMadeTextbox.Text = "asdf"; // does not compile
// can't say frm1.programmaticallyMadeTextbox.Text="asdf"
// why not?
// I suppose because programmaticallyMadeTextbox is not public
// how can I make it public like my drawnTextBox is public?
It is meant to add a textbox to FormX, and set the textbox's text property the same way I can do with the drawnTextBox.
The reason why I can do that with drawnTextBox, is that I set the modifier property to public. I'd like to somehow do that with the textbox I made programmatically.
Usually I do this when adding the controls dynamically, give them a (proper)name and find the control from the collection when it is needed.
TextBox textbox = new TextBox();
// other properties
textbox.Name = "newtextbox"; // Any unique name
form1.Controls.Add(textbox);
Now you could access the elements.
var textbox = Controls.OfType(TextBox)().FirstOrDefault(x=>x.Name == "newtextbox");
if(textbox != null)
{
// access element.
}
You could add this line to the Form1 class in the Form1.cs file.
public TextBox tb;
and change your example to
Form1 frm1 = new Form1();
frm1.tb = new TextBox();
frm1.Controls.Add(frm1.tb);
or maybe you could get access to your TextBox using frm1.Controls.OfType<TextBox>().Single() or frm1.Controls.OfType<TextBox>().First() or frm1.Controls.OfType<TextBox>().Last().

Is there any other way to access open forms in C#?

Application.OpenForms["formname"];
Is there any other way to access an open form. My application doesn't see this form although it is opened. I dont know why.
Isn't really necessary a name to get an open form.
You can get the form you want by index:
Form frm = Application.OpenForms[0] //Will get the main form
Form frm = Application.OpenForms[1] //Will get the first child
Forms in the OpenForms collection are ordered in the same way that you create it
Otherwise, an alternative is to save a reference to the form and then accessing it by this reference.
//Where you want to save the reference:
Form theForm;
//Where you create the form:
myClass.theForm = new MyForm();
//Where you want to get that form:
MessageBox.Show(myClass.theForm.Caption);
(myClass is the class that will hold your reference to the form, supposing you are accessing it from different classes)
(Also, see if you are affected by this: Application.OpenForms.Count = 0 always)
I recommend you to firstly debug your code to check what is the Form actual name which you want to load:
foreach (Form form in Application.OpenForms) {
string name = form.Name; //check out this name!!
//print, or anything else will do, you only want to get the name
//note that you should be able to get any form as long as you get its name correct
}
And then, once you know what is wrong with your code, simply do:
Form form = Application.OpenForms[name]; //use the same name as whatever is available according to your debug
To get your form.
To check more on the possible bugs, See Hans Passant's Post
You have to instanciate first a Form. after that you have access to it:
Form1 formname = new Form1();
Application.Run(formname);
// access to form by formname.yourproperty
To access the form using this property your form must have a Name.
Remember its not the instance name nor the the form Text:
Form1 f1 = new Form1(); //not "f1" is the "Name"
f1.Text = "it is title of the form"; //neither "Text" is the "Name"
f1.Name= "its the name"; //it is the "Name"
Sample:
frm_myform form1 = new frm_myform();
frm_myform.Name = "form1";

Unable to return value to DataGridView in the other form

I have a datagridview called logDataGridView in my AnalyzerForm project.
In order to access to it's DataSource property from the other from, called Form2, in the project, below access field has been defined into the AnalyzerForm.Designer.cs:
Public System.Windows.Forms.DataGridView _DGV
{
get {return this.logDataGridView;}
set {logDataGridView.DataSource = value;}
}
And finally, i try to use a filled DataTable called t from the Form2:
AnalyzerForm AZ = new AnalyzerForm();
AZ._DGV.DataSource = t;
Nothing will be shown into the logDataGridView!!!
Does anybody have any idea about the wrong part?
Actually the wrong part of the progress is just reinstantiation of the parent form, as below:
AnalyzerForm AZ = new AnalyzerForm();
One must use the very parent form reference, is which responsible for launching the child form. It is possible to define a secondary constructor for the child parent and feed a parent form object just inside of it:
ParentForm pForm;
public childForm(ParentForm FRM)
{
pForm = FRM;
// Then component initializing...
}
Finally, the required component of the parent form (is which a datagridview, in my case), is possible:
pForm._DVG.DataSource = t;

Display Message in MDI Parent Status Bar from Child c#

This is simplest possible thing, but I cant update text on status bar. I just started working in c# but cannot find solution. I tried below code:
Mdiparent
public void StutasText(string text)
{
toolStripStatusLabel.Text = text;
}
Child form
MDIParent1 obj = new MDIParent1();
obj.StutasText("Hello world");
obj.Refresh();
Its not showing status text in the status bar.
Where did I go wrong?
In the MDI Parent form, I assume you have toolStripStatusLabel1. If you dont have, you can add this by clicking on the little black arrow in the menuStrip control.
Option 1
In your MDI Parent (let's assume, frmMain is the MDI Parent form) form where you have the StatusStrip, goto frmMain.Designer.cs file and find the place
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
make this,
public System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel1;
Then from your child pages you can access like below.
ToolStripStatusLabel statusStrip=((frmMain)(frmMdiChild.MdiParent)).toolStripStatusLabel1
Option 2
Declare a public property which will return the toolStripStatusLabel1 control or method where you can set the text property of the toolStripStatusLabel1 in the MDI Parent form. If you return the menuStrip1 itself then you have access to all the properties of that control. If you declare a method, which will set the text property of the toolStripStatusLabel1 then you can only set the text. Decide on what you want, based upon your requirement.
An implementation which returns the menuStrip1 control.
public ToolStripStatusLabel GetStatusBar
{
get
{
return this.toolStripStatusLabel1;
}
}
then from your child pages, you can use,
ToolStripStatusLabel statusStrip=((frmMain)(frmMdiChild.MdiParent)).GetStatusBar;
Option 3
To make it little bit more prettier, you can declare a method in a common class. Then you can reuse this in other child forms.
public void ShowStatusbarMessage(Form frmMdiChild, string message, NotifierType notificationType)
{
ToolStripStatusLabel statusStrip=((frmMain)(frmMdiChild.MdiParent)).GetStatusBar;
statusStrip.Text = message;
if (notificationType == NotifierType.SuccessInfo)
{
statusStrip.ForeColor = System.Drawing.Color.Green;
}
else if (notificationType == NotifierType.Warning)
{
statusStrip.ForeColor = System.Drawing.Color.Orange;
}
else
{
statusStrip.ForeColor = System.Drawing.Color.Red;
}
}
Here, NotifierType is an enum
((mdiMain)MdiParent).toolStripStatusLabel.Text = "My Text";
//but you must change the modifier property of toolStripStatusLabel to public etc
You're creating a new instance of MDIParent1, not using the instance that is shown/the instance your child form belongs to.
You could try using
this.MdiParent
instead of
new MDIParent1()
((frmMDI)this.MdiParent).yourcontrol.yourproperty=yourvalue;
frmMDI is unique name of MDI form.
First
In "mdi parent name".Designer.cs, change the type or member private to public
Second In your code add the next code
(("mdi parent name")MdiParent).toolStripStatusLabel.Text = "your text";

Creating Edit dialog box in Windows Forms C#

I have Form1.cs which has two buttons say "ADD" and "EDIT".
Clicking "ADD" shows dialog Form2.cs.
Form2 has a TextBox and a ComboBox. Say we enter value "A" in textbox and select "A" from ComboBox.
Then close Form2.
Then when EDIT button is clicked on Form1, Form2 should show up with "A" in textbox and "A" selected in ComboBox.
This is a simple explanation. The real form I am using has around 10-12 different controls including combobox, checkbox, textbox etc.
My main doubt is where and how do we save these control values.
Is there a specific approach to this type of DialogBoxes that I am missing?
Create class, that would store values that you want to pass (let's call it Foo).
Form2 should then have a property. In the setter of the property, set controls:
public partial class Form2 : Form
{
private Foo _bar;
public Foo Bar
{
set
{
_bar = value;
//set your controls here
}
}
On Edit button, set property like this:
Form2 form2 = new Form2();
form2.Bar = bar; //bar contains values to edit
Then put a Save button on Form2, that would save values back from controls to this object.
For every control I would have a field in Foo class, eg. string for textboxes, bool for checkboxes and enum or int for comboboxes (where integer value would equal selected index).
Alternatively, you could use Dictionary class instead and have key and value pair for every control.
You can also have some enum, if your form looks or behaves differently in New and Edit mode.
Your Dialog Form should have a field containing the properties/fields you want, a copy a business object for example. Then you pass it or initialize it in your dialog constructor or Load, depending the behavior you want. From there you can create / initialize your controls.
If you want a built in system you may wanna take a look to the PropertyGrid (which you could embedded in a dialog (to fit your question))
Do you want to just load the last value user entered there?
For instance he writes "text" on the textbox and chooses "A" combobox it should be pre-selected next time you open it?
Edit: Then instead of closing it using Form.Close make it so that it hides. Form1.Hide. Next time it opens values are still saved. Unless application has been closed. In the other hand, users might click on the close button in the windows form. You can either make it "unclickable" throught proprieties or just configure it using events i think.
Create a method on Form2, where you will set values into textBox and select an item in comboBox. Call this method just after instantiating form2 and before showing it.
Example:
public Form2()
{
InitializeComponent();
comboBox1.Items.AddRange(new string[] { "a", "b", "c" });//fill comboBox your way on a loading time
}
public void UpdatingControls(string a, string b)
{
textBox1.Text = a;
comboBox1.SelectedText = b;
}
//on form2;
Form1 f2;
private void OpenForm2Button_Click(object sender, EventArgs e)
{
f2 = new Form2();
f2.UpdatingControls("a", "b"); //a will go into textBox, b will be choosen in comboBox
}
public Form2(string form1Textbox)
{
InitializeComponent();
form2Textbox.Text = form1Textbox;
}

Categories

Resources