Trying to use a reference to my mainform - c#

Yesterday I asked a question how it is possible to access my mainform from another form to give it the focus.
Giving focus back to main form
The solution was to add a reference to the mainform when the new form is called.
This works great for .focus() by doing:
Form mainform_instance;
public NewForm(Form mainform)
{
this.mainform_instance = mainform;
InitializeComponent();
}
However now I need to access a 'custom function' on the main form from my new form.
But I cannot access it since it is declared as Form mainform_instance and the Form type doesn't have my custom function. (at least that's what I think what goes wrong.)
So I thought I try:
MainForm mainform_instance;
and
Namespace.MainForm mainform_instance;
But both don't work.
How can I access my function (foo()) on the mainform from the new form?
EDIT
As requested by Adam Maras in comment:
namespace Namespace
{
public partial class MainForm : Form
{
public MainForm()
{
InitializeComponent();
}
EDIT2
MainForm code which calls the NewForm:
newForm = new Namespace.NewForm(this);
newForm.Show();
NewForm construct:
namespace Namespace
{
public partial class NewForm : Form
{
// here I tried to do MainForm mainform_instance as well as in the construct param
Form mainform_instance;
public NewForm(Form mainform)
{
this.mainform_instance = mainform;
InitializeComponent();
}

In the NewForm objects Load event, this.Owner would return your main form object if you invoked NewForm with a ShowDialog(this) call.
// in your MainForm
NewForm nwForm = new NewForm();
nwForm.ShowDialog(this);
// inside your NewForm object, after loading
(this.Owner as MainForm).Foo();
I realize I misdirected you in your previous post by asking you to use this.Parent(); I should have remembered it is this.Owner(). Apologies!

If you know exactly what kind of form type to use, simply change the code to reference that kind of form.
MainForm mainform_instance;
public NewForm(MainForm mainform)
{
this.mainform_instance = mainform;
InitializeComponent();
}
If you can have multiple types of forms then you can try to cast it to MainForm prior to using it, and if successful - use it.
MainForm mainForm = mainform_instance as MainForm;
if (mainForm != null) mainForm.foo();

Make the custom function public and pass the reference of main form to the new form. Then using the main form's reference you will be able to call any public method of main form from new form

Is your function declared private?
I never recommend a main form reference to any other form ...there is always a better way. That said, if you have a method that needs to be executed from the form, you must pass a reference to that main form method.
public NewForm(Form mainform, Action mainFormMethod)
{
this.mainform_instance = mainform;
InitializeComponent();
mainFormMethod.Invoke(); // or just mainFormMethod();
}
See MSDN: Action Delegate
There is also the Action<T> ...be sure and check those out. If your method requires a return, you will need to check out Func<TResult>
For the records, I would recommend re-thinking sending the reference to the main form.

Related

C# Specific value passing between forms without new instance

I have a C# application that allows the user to log certain events that occur in a game. For simplicity I'll call them ParentForm and ChildForm.
ParentForm is used 99% of the time, to log common events. This is represented as the user clicking a PictureBox and the Tag property of that PictureBox being added to a ListBox. When a "rare" event occurs, the user can click a "log rare event" button on ParentForm to open ChildForm which opens a set of "rare event" PictureBoxes, which function the same as in the ParentForm. The challenge is that I want these common and rare events to be logged to the same ListBox, so I am trying to find out how I would get a PictureBox click (and subsequent Tag from this PictureBox) on the ChildForm to the ListBox on the ParentForm.
The ParentForm does not close while ChildForm is open, and needs to stay open.
In the ParentForm code, I already have the code needed to capture one of the PictureBox clicks and grabbing the Tag, as well as handling dealing with adding it to the ListBox, so it'd be nice if I could just use these.
Here's what I've tried so far for the Parent:
// This file is EventLogger.cs
using rareEvent;
namespace mainWindow {
public partial class EventLogger : Form {
// In the ParentForm (listeners for PictureBox clicks are handled elsewhere)
public void pictureBox_Click(object sender, EventArgs e) {
PictureBox pbSender = (PictureBox) sender;
// Open new window and handle "rare" drops
if (pbSender.Tag.ToString() == "rare") {
// Open rare form
EventLogger.RareForm rare = new EventLogger.RareForm();
rare.Show();
}
}
}
}
and here's the child:
// This file is Rare.cs
using EventLogger;
namespace rareEvent {
public partial class rareEventForm : Form {
// In the ChildForm
private void pictureBox_Click(object sender, EventArgs e) {
// Does not compile if form is not instantiated, but I do not
// want a new instance
EventLogger form;
form.pictureBox_Click(sender, e);
}
}
}
I figured something like this would work, but it gives the error
The type or namespace name 'EventLogger' does not exist in the namespace
'mainWindow' (are you missing an assembly reference?)
Any help would be much appreciated. All the other examples I've found of value passing between forms all seem to create new instances which I don't want or were 8 years old and didn't work.
Appreciate it!
Edit: Code updated to have using <namespace> in each file. The problem still exists of not being able to send values between both forms without using new. (See comment to this answer)
In the first form create an instance (of it) here like my form1. It must be static and all datatypes you want to access should be public.
//FORM1
public partial class Form1 : Form
{
//Instance of this form
public static Form1 instance;
//For testing
public string myProperty = "TEST";
//Assign instance to this either in the constructor on on load like this
public Form1()
{
InitializeComponent();
instance = this;
}
//or
private void Form1_Load(object sender, EventArgs e)
{
//Assign the instance to this class
instance = this;
}
Then in form2 when calling EventLogger.RareForm rare = new EventLogger.RareForm(); instead of new form do
EventLogger.RareForm rare = EventLogger.RareForm.instance
Or in my case
Form1 frm = Form1.instance;
I then check the property of form 1 FROM form2 like so
Console.WriteLine(frm.myProperty);
Output was "Test"
Any trouble shout.

Calling event/methods of one form from another form without reopening form

'Form1' and 'form2' are open in mdi. when i press button in 'form1' it should call evevt or methods of 'form2', e.g. like 'checkbox' checked ,refresh grid
for that I have code for form2(child form):
public partial class Form2: Form
{
private Form1 Form1_Obj1;
public Form2(Form1 Form1_Obj2)
{
InitializeComponent();
Form1_Obj1 = Form1_Obj2;
}
public Form2()
{
InitializeComponent();
}
for calling events from form1 I have code
Form2 obj=new Form2(this);
obj1.chkSortPlace.Checked = true;
or
obj1.chkSortPlace_CheckedChanged(null, null);
problem is event is call but code in event i.e.assign datasource to gridview is not occur.it will not give error but result is not display grid not refresh
A trick to call a method of some other forms in c#.Net is to use Application.OpenForms here is a sample code
foreach (Form frm in Application.OpenForms)
{
if (frm is Form2)
{
//Put your code here.
}
}
Edit: changed the answer because I misunderstood what OP was trying to do.
The reason you are unable to manipulate chkSortPlace is because by default all controls that you add to a form are marked as private.
Go to Form1, right click on it, select "View Code" and add the following:
public bool SortPlaceChecked
{
get { return chkSortPlace.Checked; }
set { chkSortPlace.Checked = value; }
}
Then, when you want to change the state of chkSortPlace from your other form, simply use the public property you added above.

Can't access instance of form created by the constructor of the current form

In my main form's constructor i have:
itemDisplay newForm = new itemDisplay();
newForm.Show();
elsewhere in the form i have a textbox_textchanged event where i am trying to reference a method in newForm but it won't let me access the instance much less the methods within it. The constructor is public what else am i missing?
You need to keep a reference to the newly created form as a module-level variable. Something like this:
private itemDisplay newForm = new itemDisplay();
public my_main_form()
{
newForm.Show();
}
Then you should able to access newForm anywhere from in the main form.
You can also create instance of class below
private itemDisplay newForm;
public my_main_form()
{
newForm = new itemDisplay();
newForm.Show();
}

Passing tabConrol properties from on form to another

I am using two forms in a windows form application in C#.I want to pass the tabControl's properties like its "Tabpage count" from first form to second form. Can anyone help me here?I can't create object of first form in second form and call a function beacuse for a new forn object, the tabcontrol gets refreshed.
Inside your first form create an instance of your second Form class as this
Form frm= the instance of your secand form
after that show the instance of your secand form, now you exactly have an instance of your secand form inside your first form and can use all the public properties of it
You can create static public functions exposing desired control properties like in below code.
public static Color TabColor()
{
return Form1.Fom1TabControl1.SelectedTab.ForeColor;
}
and you can access Form1 properties like below;
private void Form2_Load(object sender, EventArgs e)
{
this.Fom2TabControl1.SelectedTab.ForeColor = Form1.ForeColor;
}
First Check your class accessibility and set to public if not work set public static, maybe your namespaces is different
hope it helps
This can be achieved in two ways
Aprroach 1:
Create a public variable in Form2
public int intTabCount=0;
and in Form1, you should call Form2 like
Form2 objForm2 = new Form2();
objForm2.intTabCount = tabPageCountVariable;
objForm2.Show()
Aprroach 2:
Create a parameterized constructor and public variable in Form2
public int intTabCount=0;
public Form2(int TabCounts)
{
intTabCount = TabCounts; // and use intTabCount for your class
}
and call from Form1 like
Form2 objForm2 = new Form2(tabPageCountVariable);
objForm2.Show();
Now if you want to pass value through any events like clicking an button in Form1 which updates anything in Form2, use the below link
Passing Values Between Windows Forms c#

Fill a list of objects from another class

I know this is a basic question, but I am struggling with it for quite some time now..
I have a main form in which I have a List<Filenames> and I have another class that gets invoked by the main form. This class has to insert some entries in my List<Filenames>.
In main form, I have the list initialized as:
public List<Filenames> filenamesList = new List<Filenames>();
And in the other class I do:
MainForm mainForm = new MainForm();
mainForm.filenamesList.Clear();
//then I have a for loop in which I perform some changes
mainForm.filenamesList.Add(new Filenames { name = "filename1", id = 1 } );
//it works until here and a new Filenames is added to the list
//then we go back to the main form
The problem is that now the List<Filenames> is empty. What am I doing wrong?
I have another class that gets invoked by the main form
I suspect the problem is here:
MainForm mainForm = new MainForm();
This creates a new MainForm instance, which is not the same instance as the MainForm that invokes the function.
I would redesign this so that the function you are invoking returns a List<Filenames> (or just an IEnumerable<Filenames> to be less specific) and let the form class worry about filling its filenamesList property. Exposing data members of a form can get messy quickly since you need to pass an instance of the form to anything that must use the property.
soimething like this:
-- other class --
public IEnumerable<Filenames> GetFilenames()
{
return new List<Filenames> { new Filenames { name = "filename1", id = 1 } };
}
--MainForm--
this.filenamesList.Clear();
this.filenamesList.AddRange(otherclass.GetFilenames());
When you do this in the second form:
MainForm mainForm = new MainForm();
You've created an entirely new instance of MainForm that has no reference to the list in the original MainForm instance. You're clearing the list and adding items to it, but when you exit your second form those items are lost.
You've got to pass your original MainForm instance to the new form that opens:
public class Form2 : Form
{
private MainForm mainForm;
public Form2(MainForm mainForm)
{
this.mainForm = mainForm;
}
public void SomeMethodThatUpdatesFileNamesList()
{
mainForm.filenamesList.Clear();
...
}
}
By declaring a new MainForm using the line MainForm mainForm = new MainForm(); you are not referring to the same filenamesList. You need to get the reference to the first class, either by sending the filenamesList as a parameter to the function or by adding it as a propery in one of the classes.
If the "other class" is a child of the main form, you might be able to get a reference to the parent object, but this depends on the stucture of the program.

Categories

Resources