Activating something from a menu strip doesn't work - c#

I have a button on Form1 that starts disabled by default. I have a ConfigureForm, where I have a menu strip, with an option to enable the button in Form1.
So my code is:
private void Portal2HammerButtonEnable_Click(object sender, EventArgs e)
{
Form1 frm1 = new Form1();
frm1.Portal2HammerButton.Enabled = true;
}
But when I close ConfigureForm and look at the button, it's still disabled.

That's because you create a new Form1 and enable on that form the button. Instead, you have to pass the instance of the form you actually have open.
For design purposes you may want to use a controller class between these two forms. This will help you to simplify the complexity of passing data or actions between the two forms and will give you the power to escalate better the app..
When you open the ConfigureForm you have to do the following (in the simplest form however not recommended.)
...
{
ConfigureForm frmConfigure = new ConfigureForm(this);
}
Then inside the ConfigureForm:
public partial class ConfigureForm : Form
{
private From1 mainForm = null;
public ConfigureForm()
{
InitializeComponent();
}
public ConfigureForm(Form callingForm):this()
{
mainForm = callingForm as Form1;
}
private void Portal2HammerButtonEnable_Click(object sender, EventArgs e)
{
mainForm.Portal2HammerButton.Enabled = true;
}
}

You're creating a new form on the click of this button. What you want instead is a valid reference to the actual instance of Form1.
You have some options available:
If one of these forms is the "main" form of the application then you can ensure that it is created first and thus creates the other "sub" forms. you can override the constructors of any sub forms to include a reference to your "main" form.
You can keep references to all your important forms in a public static class such that all your forms can get to those references
You add your own public method to assign the "parent form" as a member or property of the child forms.
You can use reflection to find the instance of the "main" or "parent" form during creation or display of any child forms. If you do this, only do it once rather than upon every request. Try to cache that information.
You can read through the System.Windows.Forms namespace to find out if there's already a collection of objects through which you could iterate to find your main form.
I'd recommend option 2 or 5.

Related

How to access the same object from another Form C#? [duplicate]

I would like to set comboBox.SelectedValue when I select the row in my dataGridView on first form to populate comboBox with that value on another form,
On second form in my load event I have comboBox.DataSource, DisplayMember, ValueMember set it correctly but nothing is happening when I set selectedValue on first. Everything works great when I do it on one form
Form in Windows Forms is a class like other C# classes. The way of communicating between forms are the same as classes. You can consider this options when communicating between classes:
Manipulate second Form from first Form
You can add suitable parameters to the constructor of the second form. Then you can pass values to the constructor when creating an instance of the second form. In the second form store parameters in member fields and use them when you nees.
You can create public property or method in the second form and set those properties after creating an instance of the second form. This way you can use them when you need in the second form. This option is not limited to passing values when creating the second form. You can even use that property during the execution of second Form. Also it's useful for getting a value from it.
As another option you can make the control which you want to manipulate it public and this way you can access to it from other form. Using a method is a more recommended way of doing this.
Manipulate first Form from second form
You can create a public method or property in first form and pass an instance of the first form to second form. Then using that method/property on the passed instance, you can manipulate the first form.
You can create an event in second form and after creating an instance of second form subscribe for it in first form and put the code for changing the form in the handler. Then it's enough to raise the event in second form.
You can define a public property of type Action or some other delegate type in second form and then after creating an instance of second form, assign the property using a custom action. Then in second form, it's enough to invoke the action when you need to manipulate first form.
Also here you can make a control of first form to be public and then if you pass an instance of the first form to the second form, you can manipulate the control. It's recommended to use other solutions. It's like creating public property or method, but a method which performs specific task on the control is better that exposing the whole control. But you may need this solution some times.
Here are some useful examples about above solutions.
Manipulate second Form from first Form
Example1 - Using constructor of second Form
Use this example when you need to pass some data to second form, when creating the second form.
public partial class Form2 : Form
{
int selectedValue;
public Form2(int value)
{
InitializeComponent();
selectedValue = value;
}
private void Form2_Load(object sender, EventArgs e)
{
//Load data
this.comboBox1.DataSource = new MyDbContext().Categories.ToList();
this.comboBox1.DisplayMember = "Name";
this.comboBox1.ValueMember = "Id";
this.comboBox1.SelectedValue = selectedValue;
}
}
Then in your first form, it's enough to pass the value to Form2 when you create a new instance of it:
var value = 2; // Or get it from grid
var f = new Form2(value);
f.ShowDialog();
Example2 - using public Property or Method of second Form
Use this example when you need to pass some data to second form, when creating or even after creation of second form.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public string SomeValue
{
get { return textBox1.Text;}
set { textBox1.Text = value;}
}
}
Then in your first form, it's enough to pass the value to Form2 when you need, after creating Form2 or whenever you need to set value of textBox1 on Form2:
var f = new Form2(); //value is not needed here
f.SomeValue = "some value";
f.Show();
//...
f.SomeValue = "some other value";
Example 3 - Making a Control of Second form public
Use this example when you need to change a property of a control on second form, when creating or even after creation of second form. It's better to use public property or method instead of exposing whole control properties.
In your Form, at designer, select the control and in Properties window set the Modifiers property to Public. Also make sure the GenerateMember property is true. Then you can simply access this control using its name from outside of the Form.
var f = new Form2();
f.textBox1= "some value";
Manipulate first Form from second form
Example 4 - Create public Method or Property in first Form and pass an instance of First Form to constructor of second Form
Use this example when you need to change first Form from second Form.
In your Form1, create a property of a method that accepts some parameters and put the logic in it:
public void ChangeTextBox1Text(string text)
{
this.textBox1.Text = text;
}
Then create a constructor in Form2 which accepts a parameter of type Form1 and keep the passed value in a member field and use it when you need:
Form1 form1;
public Form2 (Form1 f)
{
InitializeComponent();
form1 = f;
}
private void button1_Click(object sender, EventArgs e)
{
form1.ChangeTextBox1Text("Some Value");
}
Now when creating Form2 you should pass an instance of Form1 to it:
var f = new Form2(this);
f.Show();
Example 5 - Using event of second Form in first Form
Take a look at this post. It's about communication between form and a control, but it's applicable to communication between forms also.
Example 6 - Injection an Action in second Form
Take a look at this post. It's about communication between form and a control, but it's applicable to communication between forms also.
Example 7 - Making a Control of first form public
In this solution you need to make a control in first form public, like example 3. Then like example 4 pass an instance of the first form to second form and keep it in a field and use it when you need. Using a public method or property is preferred.
Form1 form1;
public Form2 (Form1 f)
{
InitializeComponent();
form1 = f;
}
private void button1_Click(object sender, EventArgs e)
{
form1.textBox1.Text = "Some Value";
}
when creating Form2 you should pass an instance of Form1 to it:
var f = new Form2(this);
f.Show();

Property or indexer 'Form.MdiChildren' cannot be assigned to -- it is read only

I keep getting the error in the title, and I can't figure out where the Form is set to read-only or how I can disable this.
private void studentToolStripMenuItem1_Click_1(object sender, EventArgs e)
{
addStudent newStudentForm = new addStudent(this);
newStudentForm.MdiChildren = this;
newStudentForm.Show();
}
addStudent is a form that takes care of creating students, and populating a list of students which is kept on the main form. So I want to be able to edit data on Form1 from Form2 which is why I am using Mdi
Can anyone give me any tips on where I should be looking at what I should be looking for to fix this error?
EDIT: To be clear
Form1 = Parent
Form2 = Child
MdiChildren is just an array, which represents the current forms, which are the Mdi Childs of the dialog. You need to load the MDI child into the parent.
Something like this:
addStudent newStudentForm = new addStudent();
newStudentForm.MdiParent = this;
newStudentForm.Show();
You don't need to set MdiChildren. Moreover, you wouldn't be able to set it this way even if it wasn't readonly - it is a collection of forms, not a form.
Logically, you try to tell that "newStudentForm has current form as MDI child", and is isn't true, you actually need "newStudentForm is a new MDI child of this".
The only thing you need to do is to set MdiParent in your child form:
private void studentToolStripMenuItem1_Click_1(object sender, EventArgs e)
{
AddStudent newStudentForm = new AddStudent(this);
newStudentForm.MdiParent = this;
newStudentForm.Show();
}
P.S. Please, use proper naming for your classes. It shuld be AddStudent, not addStudent. This one letter makes code absolutely unreadable.

c# passing string to different form textbox [duplicate]

I would like to set comboBox.SelectedValue when I select the row in my dataGridView on first form to populate comboBox with that value on another form,
On second form in my load event I have comboBox.DataSource, DisplayMember, ValueMember set it correctly but nothing is happening when I set selectedValue on first. Everything works great when I do it on one form
Form in Windows Forms is a class like other C# classes. The way of communicating between forms are the same as classes. You can consider this options when communicating between classes:
Manipulate second Form from first Form
You can add suitable parameters to the constructor of the second form. Then you can pass values to the constructor when creating an instance of the second form. In the second form store parameters in member fields and use them when you nees.
You can create public property or method in the second form and set those properties after creating an instance of the second form. This way you can use them when you need in the second form. This option is not limited to passing values when creating the second form. You can even use that property during the execution of second Form. Also it's useful for getting a value from it.
As another option you can make the control which you want to manipulate it public and this way you can access to it from other form. Using a method is a more recommended way of doing this.
Manipulate first Form from second form
You can create a public method or property in first form and pass an instance of the first form to second form. Then using that method/property on the passed instance, you can manipulate the first form.
You can create an event in second form and after creating an instance of second form subscribe for it in first form and put the code for changing the form in the handler. Then it's enough to raise the event in second form.
You can define a public property of type Action or some other delegate type in second form and then after creating an instance of second form, assign the property using a custom action. Then in second form, it's enough to invoke the action when you need to manipulate first form.
Also here you can make a control of first form to be public and then if you pass an instance of the first form to the second form, you can manipulate the control. It's recommended to use other solutions. It's like creating public property or method, but a method which performs specific task on the control is better that exposing the whole control. But you may need this solution some times.
Here are some useful examples about above solutions.
Manipulate second Form from first Form
Example1 - Using constructor of second Form
Use this example when you need to pass some data to second form, when creating the second form.
public partial class Form2 : Form
{
int selectedValue;
public Form2(int value)
{
InitializeComponent();
selectedValue = value;
}
private void Form2_Load(object sender, EventArgs e)
{
//Load data
this.comboBox1.DataSource = new MyDbContext().Categories.ToList();
this.comboBox1.DisplayMember = "Name";
this.comboBox1.ValueMember = "Id";
this.comboBox1.SelectedValue = selectedValue;
}
}
Then in your first form, it's enough to pass the value to Form2 when you create a new instance of it:
var value = 2; // Or get it from grid
var f = new Form2(value);
f.ShowDialog();
Example2 - using public Property or Method of second Form
Use this example when you need to pass some data to second form, when creating or even after creation of second form.
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public string SomeValue
{
get { return textBox1.Text;}
set { textBox1.Text = value;}
}
}
Then in your first form, it's enough to pass the value to Form2 when you need, after creating Form2 or whenever you need to set value of textBox1 on Form2:
var f = new Form2(); //value is not needed here
f.SomeValue = "some value";
f.Show();
//...
f.SomeValue = "some other value";
Example 3 - Making a Control of Second form public
Use this example when you need to change a property of a control on second form, when creating or even after creation of second form. It's better to use public property or method instead of exposing whole control properties.
In your Form, at designer, select the control and in Properties window set the Modifiers property to Public. Also make sure the GenerateMember property is true. Then you can simply access this control using its name from outside of the Form.
var f = new Form2();
f.textBox1= "some value";
Manipulate first Form from second form
Example 4 - Create public Method or Property in first Form and pass an instance of First Form to constructor of second Form
Use this example when you need to change first Form from second Form.
In your Form1, create a property of a method that accepts some parameters and put the logic in it:
public void ChangeTextBox1Text(string text)
{
this.textBox1.Text = text;
}
Then create a constructor in Form2 which accepts a parameter of type Form1 and keep the passed value in a member field and use it when you need:
Form1 form1;
public Form2 (Form1 f)
{
InitializeComponent();
form1 = f;
}
private void button1_Click(object sender, EventArgs e)
{
form1.ChangeTextBox1Text("Some Value");
}
Now when creating Form2 you should pass an instance of Form1 to it:
var f = new Form2(this);
f.Show();
Example 5 - Using event of second Form in first Form
Take a look at this post. It's about communication between form and a control, but it's applicable to communication between forms also.
Example 6 - Injection an Action in second Form
Take a look at this post. It's about communication between form and a control, but it's applicable to communication between forms also.
Example 7 - Making a Control of first form public
In this solution you need to make a control in first form public, like example 3. Then like example 4 pass an instance of the first form to second form and keep it in a field and use it when you need. Using a public method or property is preferred.
Form1 form1;
public Form2 (Form1 f)
{
InitializeComponent();
form1 = f;
}
private void button1_Click(object sender, EventArgs e)
{
form1.textBox1.Text = "Some Value";
}
when creating Form2 you should pass an instance of Form1 to it:
var f = new Form2(this);
f.Show();

C# Winform close opened window when call other window

How can I close an opened window when I call a new window? That means I want only 1 child window at the time. I don't allow multi-window.
public partial class Main_Usr : Form
{
public Main_Usr()
{
InitializeComponent();
this.IsMdiContainer = true;
if (Program.IsFA) barSubItem_Ordre.Visibility = DevExpress.XtraBars.BarItemVisibility.Never;
Ordre_Liste f = new Ordre_Liste();
f.MdiParent = this;
f.Show();
}
private void barButtonItem_CreateOrdre_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
Program.AllerRetour = "Ordre Aller";
Ordre_Fiche f = new Ordre_Fiche();
f.MdiParent = this;
f.Show();
}
private void barButtonItem_OrdreListe_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
Ordre_Liste f = new Ordre_Liste();
f.MdiParent = this;
f.Show();
}
private void barButtonItem_CreateOrdRet_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
Program.AllerRetour = "Ordre Retour";
Ordre_Fiche f = new Ordre_Fiche();
f.MdiParent = this;
f.Show();
}
}
There are different ways to implement pseudo masterpage:
You can create BaseForm form with desired layout. Then inherit other forms from this BaseForm and provide custom content.
You can create MainForm form with desired layout. Then create content controls as UserControls and show them in panel.
You can create MasterUserControl with desired layout. Then create content controls by inheriting from MasterUserControl (they will have same layout). Then use your main form as browser for displaying different content controls like pages.
EXAMPLE:
Create desired layout on Main_Usr form.
Do not set it as MdiContainer
If you want to access some controls (e.g. footer or header from child forms, set property Modifiers of those controls to protected)
Open Ordre_Liste form code and change it to inherit from Main_Usr form, instead of Form
Add custom content to Ordre_Liste form
voila! you have 'masterpage'
UPDATE (for 3rd option)
Create new user control with name MasterUserControl
Create desired layout on this control, keeping space for custom content (btw don't use TableLayoutPanels - they have issue with designer inheritance).
Create new user control with name HomeUserControl and change it to inherit from your MasterUserControl.
Open HomeUserControl designer and add custom content. Also you can modify parent controls, which has protected modifier.
On your main form place HomePageUserControl
There different ways to implement navigation between controls (aka pages). Simplest way - have menu on main form. Other way - define event 'Navigate' on master control, subscribe to that event on main form, and raise it from 'pages'.
Create Form instances on a class level.
Then you can access to them from events or methods.
Form1 f1;
Form2 f2;
void OpenForm1()
{
f1 = new Form1()
f1.Show();
}
void OpenForm2()
{
f1.Dispose(); //or Hide if you want to show it again later
f2 = new Form2();
f2.Show();
}
Like:
List<Form> openForms = new List<Form>();
foreach (Form f in Application.OpenForms)
openForms.Add(f);
foreach (Form f in openForms)
{
if (f.Name != "Menu")
f.Close();
}
Note, do NOT close them directly, becuase there will come to an error, if you would try to close (or dispose) them in the 1st foreach loop. Thats why you need to put them into a list and close them there.

MDIWindowListITem Not Working

This one has really got me stumped. I have certain forms that are being instantiated. When I instantiate a form i make it a child of the mdi form by
form1.MdiParent = this;
I have set the MDIWindowListITem property of my menustrip to a toolstripmenuitem
However this toolstripmenuitem does not show the mdi child form when it is instantiated
Does any one have any ideas on this?
Any inputs/ leads / hints would be most welcome. I am using .net framework 3.5
Regards
,
You have to write your code so that it is added manually I believe.
See the example here for pointers:
MSDN help on ToolStripPanel
Edit
You're right ignore my previous entry here's the code for a very simple MDI app that appears to do what your after.
It is just two blank forms. Form1 has IsMDIContainer=true. It also has menuStrip1, which contains two items "new" (newToolStripMenuItem) and "windows" (windowsToolStripMenuItem). Clicking new will open a new child window. I have set the MDIWindowListItem of menuStrip1 to windowsMenuStripItem. When a new child window is opened clicking on windowsMenuStripItem produces a drop down that shows all windows open.
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private int count;
public Form1()
{
InitializeComponent();
}
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
count++;
//Set a window title text as this is what is shown in the window list.
Form2 newForm = new Form2() { Text = string.Format("Window {0}", count) };
newForm.MdiParent = this;
newForm.Show();//<--- this needed to show window in list.
}
}
}
There is no code in Form2.
The child windows only show below windowMenuStripItem once Form.Show() has been called.
Without this they do not show in the list.

Categories