Proper instatiating a WinForm via string in C# - c#

I am working on a Winforms application that uses base window (e.g. Form1) and many other windows (e.g. Form2, Form3, ...). All of these windows have their property TopLevel set to false, no border and I am placing them in the Form1 when I need them. I am not skilled enough or do not have the brain capacity to solve this issue:
public void ShowForm(string strNewForm) {
var frmNew = Activator.CreateInstance(Type.GetType(strNewForm)) as Form;
frmNew.TopLevel = false;
frmNew.Size = new Size(rctForm.Width, rctForm.Height);
frmNew.Location = new Point(rctForm.X, rctForm.Y);
frmNew.InitializeForm(strActualSection, strActualSubSection);
frmNew.Parent = this;
frmNew.Show();
}
The strNewForm variable contains the name of Form to show. All the methods and properties in each Form can be used as these all are inherited from base class Form. Problem is with InitializeForm() which I use in each form (Form2, Form3, ...) to do various stuff. I know my problem is in this line:
var frmNew = Activator.CreateInstance(Type.GetType(strNewForm)) as Form;
When strNewForm contains string "Form2" and I change as Form to as Form2 it works just fine. I know I need to change it to proper name each time, but I don't know how. I tried to use this:
Type frmType = Type.GetType(strNewForm);
var frmNew = Activator.CreateInstance(Type.GetType(strNewForm)) as frmType;
But it throws an error CS0118: frmType is a variable but is used as a type. I don't know how to solve this, I tried many solutions and I googled for half a day straight and I am still lost. Any insight would be really helpful.

You cannot use a run-time variable to create strongly-typed code.
You have to provide a compile-time type after the as.
If you know it's a Form then all you can do is this:
var frmNew = Activator.CreateInstance(Type.GetType(strNewForm)) as Form;
If you need specific methods or properties then use a custom Form as your base-type and use that in the as.

Why won't you pass a Form object in your ShowForm method?
public void ShowForm(Form newForm)
{
newForm.TopLevel = false;
newForm.Size = new Size(rctForm.Width, rctForm.Height);
newForm.Location = new Point(rctForm.X, rctForm.Y);
newForm.InitializeForm(strActualSection, strActualSubSection);
newForm.Parent = this;
newForm.ShowDialog();
}

Related

Accessing components of another form

I have two Forms in my application. A Form has the following fields: txtPower, txtTension and txtCurrent. I would like to access the values ​​filled in these TextBox through another Form. In the second Form I instantiated an object of the first Form (MotorForm), however I do not have access to the TextBox.
public MacroForm()
{
InitializeComponent();
MotorForm motorForm = new MotorForm();
motorForm.Show();
}
Is there any way?
Please do not expose the controls in your form. Never. (Unless you have a really good reason.)
If the problem is simple enough not to use MVVM (or the like) in your program (which you should consider for every program that's but trivial), you should expose the values of the instantiated form via properties. Think
public string Power
{
get { return txtPower.Text; }
set
{
if(ValidatePower(value))
{
txtPower.Text = value;
}
else
{
// throw ??
}
}
}
If we can make a sensible assumption about the type of the value we could extend this to
public double Power
{
get
{
// parse the value
// validate the value
// throw if not valid ??
// return the value
}
set
{
// validate the value
// set the value in the text box
}
}
If you exposed the txtPower object, you'd make the instantiating class depend on implementation details of the instantiated class, which is virtually never a good thing.
It seems that your problem is a perfect situation for using ShowDialog for opening your form.
To accomplish this, you need to change the Modifiers property of the controls you want to access on MotorForm and set them to Public. And also set the DialogResult property of your form somewhere to a desired value i.e OK. Anyway the easier way to do this is to set it on the button that is supposed to close the form. Suppose OK or CANCEL buttons.
Then you can create your form this way:
MotorForm motorForm = new MotorForm();
if(motorForm.ShowDialog() == DialogResult.OK)
{
string myValue = motorForm.txtPower.Text; //you can access your values this way
}

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;

How to set MDIParent property of Child form in nonMDI Class?

I am working on MDI app which have Child Forms. I have to show Child Window once a certain conditions is met.
I created a separate Class named clsDashbord having method loadDashboard() which is supposed to load frmDashboard already designed. Code is given below:
public void loadDashboard(String userName)
{
_Dashboard = new frmDashboard();
_Main = new frmMDI();
// _Dashboard.MdiParent = _Main;
_Dashboard.Text = userName;
_Dashboard.Show();
}
Form does not show up if I set MDIParent to Main which is instance variable of MDI Form otherwise it gets displayed. How to do it?
It looks more like a scoping problem by looking at line '_Main = new frmMDI();'
follow these steps:
create a class named 'ReferenceTable'
create a static variable named _Main in ReferenceTable
set ReferenceTable._Main = new frmMain(); // in Program.cs
set childform.Parent = ReferenceTable._Main //in all your child form
code before calling Show() or showDialog() methods

Trying to get the value of a text box

I'm creating a sql statement in c#, and I am trying to get the value from a text box in a previous form:
SqlParameter PeriodFrom = new SqlParameter("#PeriodFrom", SqlDbType.VarChar);
PeriodFrom.Value =
I am just unsure of what goes after the equals sign. I tried the form name.textbox name.
In the code behind of the form, inside the form class, you can declare a property:
public string TextBoxValue
{
get
{
return textBoxName.Text;
}
}
And you can use it with your SqlParameter like this:
SqlParameter PeriodFrom = new SqlParameter("#PeriodFrom", SqlDbType.VarChar);
PeriodFrom.Value = FormClassName.TextBoxValue;
Edit:
This wouldn't work since the Form class object is not static and it wouldn't persist. To make this work, you would need to make changes to the Program class. You would need to add a static Data member in the Program class like this:
public static FormClassName form;
and would need to pass this in the main method as below:
form = new FormClassName();
Application.Run(form);
And in the SQLParameter you can pass it like this:
SqlParameter PeriodFrom = new SqlParameter("#PeriodFrom", SqlDbType.VarChar);
PeriodFrom.Value = Program.form.TextBoxValue;
I tried to give you one of the ways to get the value but I do not think this is a good practice. Ideally, for passing values between forms, or layers you need to have some mechanism for storing and retrieving values, like a context, or Session. This is not the solution but a work around. And I take no responsibility if the code gets messed up cause of the above changes. :)
If your TextBox is publicly declared on your form, then you will be able to access its properties from the scope with which it was created in.
PeriodFrom.Value = otherForm.TextBoxName.Text;
If the 'previous' form object is not available to you now, then you will have to retrieve the value and pass it in as a parameter into your new form (or something of the sorts). Please supply more code/details if you want help here.
Change your textbox's modifier property to Public
then
formname.textboxname.Text
<%# PreviousPageType VirtualPath="~/SourcePage.aspx" %>
if(PreviousPage != null)
{
if(PreviousPage.IsCrossPagePostBack == true)
{
PeriodFrom.Value =PrevForm.TextBox.Text;
}
}
else
{
PeriodFrom.Value = "Not a cross-page post.";
}
YourPreviousForm.YourTextBox.Text
Get the value of textbox by using Text property of TextBox.
PeriodFrom.Value =PrevForm.TextBox.Text;
As you are saying that there is no accessbile due to protection level, you need to work on the access modifier of form from protected to public so that it can be accessible.

Categories

Resources