I've tried looking this up and I couldn't find anything that I understood.
But what I'm trying to do is create a class with all my functions in, then call it from the parent form.
And one of these functions contains adding controls to the parent form, but I cannot find out how to do this, can somebody help me please and explain it along the way?
Many thanks,
Jarrod
Typically, I'd just add a reference to the parent form in the lower class and initialize it in the constructor. Something like this:
public form MyForm : Form
{
Foo myFoo;
public MyForm()
{
this.myFoo = new Foo(this);
}
}
public class Foo
{
private MyForm parentForm;
public Foo(MyForm parent)
{
parentForm = parent;
}
}
Then you can reference the parent form and manipulate it how you wish. It also works for static classes, too.
Try this;
In your class use this method to add controls to Parent form
public static void AddControl(Form ParentForm,Control control,Point location)
{
control.Location=location;//This is only to show you
Parent.Controls.Add(control);//how it can be done.You can replace this logic with yours
//but make sure to add this Parent.Controls.Add(control),where control will be the name of your Control.
}
Then whenever you need to add a control call the function as;
ClassName.AddControl(this,new TextBox(),new Point(10,10));//Change ClassName to your class's name.
Anything else please let me know.
Related
I want to create a parent class who handles setting up all the control properties for a map, because I need that functionality in multiple forms. Since you can not pass anything besides parameters to your child function to the parent class, I have no idea how to continue. Setting up an extra method where you have to add the control to the parent class feels kind of unclean because I need to check the reference each time I call it.
Maybe you have some ideas how to implement this problem. Thanks!
public abstract class MapForm
{
protected MapForm(GMapControl mapControl)
{
MapControl = mapControl;
}
...
}
public class TestForm : MapForm
{
public TestForm(string searchValue = String.Empty) :
Base(this.mapControl) // cant do that of course
{}
...
}
I have a main form that acts as a "Wizard" for a bunch of different user controls. I have one user control with relatively basic operations, and I am trying to create a new user control that inherits this basic user control.
However, the base user control has a variable containing the main form (so the user control can access the wizard control functions in the main form). When I create a new "inherited user control" the Designer complains that the reference to the main for has not been set to an instance of the object. I set the reference to the MainForm during runtime when I create an instance of the base user control.
Is there a way to make this work? Below is some simplified code demonstrating my problem.
MainForm.cs:
public partial class MainForm : Form
{
public string exampleString = "From MainForm";
public MainForm()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
BaseControl base = new BaseControl();
base.mainForm = this;
{
}
BaseControl.cs
public partial class BaseControl : UserControl
{
public MainForm mainForm { get; set;}
public TestPanel()
{
InitializeComponent();
string needed = mainForm.exampleString; //Object reference not set to an instance of an object here
}
}
So when I try to create a user control that inherits BaseControl through Solution -> Add -> New Item -> Inherited User Control and select BaseClass, the designer complains of the "Object reference not set to an instance of an object" error at the string needed = mainForm.exampleString line in BaseControl.cs.
Any help with this would be greatly appreciated. Hopefully this is enough information for you to understand what I am trying to do.
Thanks.
The code which you shared will not work, neither at run-time nor in design-time.
You are trying to use mainForm.exampleString in constructor of BaseControl while mainForm will be assigned just after creating an instance of BaseControl.
In such cases, specially when you want to have design-time support, you can derive from ISupportInitialize interface and override BeginInit and EndInit.
Example
The following control implements ISupportInitialize. If you drop an instance of the control on the form, at run-time, it tries to find the parent form and if it was MainForm tries to use public members of the MainForm:
using System.ComponentModel;
using System.Windows.Forms;
public class MyControl : Control, ISupportInitialize
{
public void BeginInit()
{
}
public void EndInit()
{
var parent = this.FindForm() as MainForm;
if (parent != null)
{
//Access to MainForm members
}
}
}
This is just an example that shows how to use ISupportInitialize. In action, it's not a good idea to have a dependency to a specific type of parent form. A better idea as already mentioned in Jimi's comment is relying on interfaces. For example you can have a property of ISomeInterface in your control. The interface should contain the methods or properties which you want to have for the parent of your control. Then implement the interface in some forms. Then after you dropped an instance of your control at run-time or design-time, assign the form to the property.
I have a class for global variables, like this:
internal static class GlobalVariables
{
public static PortBrowserForm open;
}
The PortBrowserForm class is a Windows Form class that has a timer and want to use its properties, like this (in another form):
// In that other form...
GlobalVariables.open.timer1.Enabled = true;
But I cannot call it. I can only call a function from GlobalVariables.open variable (which is a form already). Please help.
GlobalVariables.open.timer1.Enabled = true;
To make the above code work you need to make the timer1's modifier public or atleast internal. But... Don't do that, never expose fields public because you don't get control over who is doing what.
Instead create a method which does the job for you.
class PortBrowserForm : Form
{
public void SetTimerEnabled(bool enabled)
{
timer1.Enabled = enabled;
}
}
Then use
GlobalVariables.open.SetTimerEnabled(true);
Quick and Dirty
Check PortBrowserForm .designer.cs/vb file there you can find the declaration of all controls of the form. Change its access level to public from there and you can access that from any form just by creating forms instance.
Update:
To access one forms control in another you need to pass the first form in the constructor of another. Suppose we have two forms
Form1.cs
Form2.cs
In some event of form1 , call form2.
frm1Btn_Click()
{
form2 f2 = new form2(this);
f2.Show();
}
Create a overloaded constructor in form2 with Form1 as parameter and pickup form1 and its all controls.
I've been trying to compile all my classes into a class library which is a really nice feature. My goal is to have all my code in there that doesn't include the code for a specific application. When I try to add a class that references the parent form I run into issues because there is no parent form in the class library. How do I create a reference to a form that it yet unknown until the parent class is created in the application?
public class Form1 : Form
{
private Child child;
public Form1()
{
child = new Child(this);
}
}
public class Child
{
private Form1 parent;
public Child(Form1 parent)
{
this.parent = parent;
}
}
This code works in a standard application, but when I add the Child class to the class library, the "Form1" text will not compile because Form1 is not included in the class library. Is there any way around this? Thank you for any help.
As Form1 derives from Form, why not take Form as a parameter to the constructor of Child?
public class Child
{
private Form parent;
public Child(Form parent)
{
this.parent = parent;
}
}
This will at least break the dependency on your application from your class library, but it will still require a dependency on WinForms for Form. It depends on what you intend to do with parent in your code though as to whether this is sufficient.
Use below code
Parent.FindForm()
I need to call "panel.invalidate" outside my form (WINform) class also I need to change some other controls as well, I read similar question here, and tried what they said, but it didn't work and I wasn't convinced at all.
The answer I read was about exposing a public method like this:
public void EnableButton(bool enable)
{
this.myButton.Enabled = enable;
}
Also I made a static instance in the other file
static Form1 myForm = new Form1();
Any useful suggestions??
The problem is the "myForm" reference. It is a reference to an instance of Form1 that isn't visible and doesn't match the one that the user is looking at. It can't be a match, you created a new one.
Whatever class needs to update the form must have a constructor that takes a Form1 reference. You can create the class object in your Form1 constructor or Load event, pass "this". Using Application.OpenForms[0] is another way to get the reference, one you should not use.
Are you updating from the same thread? Otherwise you might need to use Invoke.
Here's a nice short article about how to do that:
http://blogs.msdn.com/csharpfaq/archive/2004/03/17/91685.aspx
Control.Invalidate() is a public method, but the control itself is most likely not public. You will have to expose the call to Control.Invalidate() through a public facing method in your form or by marking the control in question as public.
public class MyForm : Form {
private TextBox tbxName = new TextBox();
public InvalidateTextBox() {
tbxName.Invalidate();
}
}
OR
public class MyForm : Form {
public TextBox tbxName = new TextBox();
}
public class SomeOtherClass {
public void InvalidateTextBox(MyForm form) {
form.tbxName.Invalidate();
}
}