Passing forms as a Parameter

Experts,

I`m using C# .NET VS 2008. I was wondering if passing Forms/UserControls as Paramaters to the constructors of Classes is a good practice.

Lets say, I have a Class called ExpertsClass and I want to access the controls of the main form.

Can I do something like this?
//Form1.cs     
MC = new ExpertsClass(this);

//ExpertsClass.cs
//Constructor
public ExpertsClass(Form1 F)
{

}

Open in new window

San24Asked:
Who is Participating?
 
keeghiCommented:
Hi San24,

I wonder if your question has been answered. If I am not wrong, the main point of your question is to do separation between the user interface and the logic.

If we talk about that separation, we will not go far from design pattern. The design pattern is such a guideline to compose class, arrange the structure, etc.

In term of user interface, there are several design pattern, such as MVC (Model View Controller), MVP (Model View Presenter), and MVVM; not to mention some unpopular design patterns.

This is a big topic to discuss in a forum, but let me know if you are interested to know more.

Thanks
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
No problem with that.

You might want to create classes that will work equally with different forms, and maybe even put it in a dll so that it can work with many applications.

In order to do that, you would have to let the class know of the form on which to work, probably through a property.
Initializing the property in the constructor of the class is in fact better than instantiating the object and then set the property, because it lets you do the 2 jobs with only one call between the application and the dll that contains the class.
0
 
San24Author Commented:
James..If it`s not too much to ask, can you provide an example.

Something like this? See code.

/Form1.cs     
MC = new ExpertsClass(this);

//ExpertsClass.cs
//Constructor

public Form1 Fs = null;     //Property

public ExpertsClass(Form1 F)
{
  Fs = F;
}

Open in new window

0
Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Jacques Bourgeois (James Burger)PresidentCommented:
Almost it.

However, unless you have special needs, the declaration of Fs in the class is usually private instead of public, because usually, you will be using that reference to the form only inside of the class.

One question to ask however, something I did not catch in you first post.

Since you are declaring an instance of ExpertClass inside of Form1, and since ExpertClass takes only objects of type Form1, do you need an external class to handle some operations? Couldn't the code you intend to have in ExpertsClass simply be included in Form1?

What is the purpose of ExpertsClass? Will it be used with other forms?
0
 
käµfm³d 👽Commented:
Lets say, I have a Class called ExpertsClass and I want to access the controls of the main form.
Is the new class going to be running on a thread other than the one that started the form?
0
 
Jacques Bourgeois (James Burger)PresidentCommented:
@kaufmed

I cannot say for sure, I never encountered a case where it was important for me to check for that condition. But my experience leads me to think that it depends on how you do it.

The way San24 is doing it, since the form creates the instance of the ExpertsClass, they would run on the same thread. If it was not the case, all the objects you create would be in different threads.

If you were going to create the form from inside the ExpertsClass however, it would be different. Forms are always created on a new thread. Forms are always created on their own thread. If it was not the case, you could not have 2 forms working at the same time. You would need to close one form before the user could type into another one.
0
 
käµfm³d 👽Commented:
@JamesBurger

You cannot directly access the controls of a Form from a thread other than the thread the Form was created on. To access the controls, you have to use a delegate. If San24 created a new Thread (via new Thread, BackgroundWorkder, ThreadPool, etc.) inside of the ExpertsClass, or if an instance of ExpertsClass were itself passed to a new Thread, then you would have to do the appropriate invoking in order to safely access the controls of the Form.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
Passing a Form/Control into a class is a "tightly coupled" solution because you can only use it with that specific type of form/control.

A different approach would be to utilize a "loosely coupled" solution.  This approach would use EVENTS to pass data from the class back out to the Form.  This would be done by subscribing to the events of the class with AddHandler when the class is created.
0
 
Mike TomlinsonMiddle School Assistant TeacherCommented:
*Typically all forms run in the same main UI thread.  You have to go out of your way, under special circumstances, to make forms run in their own thread.  (and that usually causes problems)
0
 
San24Author Commented:
Thanks all for the feedback. I was thinking about this a bit more and I was thinking instead of passing Forms as arguments to classes, I can take a different approach.

Here is what I want to do.

Lets think about it this way, I have a File and this can be of different types, lets call them Modules. These Modules need to inherit some of the base properties of the File.

I need a good way of propagating information between the File and the Modules.

So, I was thinking of two ways of doing this.

Approach A] I could use Inheritance. Since UserControls can`t be inherited. I was thinking, I`ll create a Class for each UserControl and then use Inheritence.

Example - FileUserControl will have an instance of FileClass.
                 ModuleA will have an instance of ModAClass which inherits from the FileClass.

I`m guessing the advantage would be I`m separating the UI and the logic.

Is that a good approach.

Approach B] I pass parameters into the Constructors. Look at the code below.

or Should I just pass Forms as arguments?




/// <summary>
    /// Main Form
    /// </summary>
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        public FileUCntrl FUCntrl = null;
        public enum ModuleType { A, B }

        /// <summary>
        /// Lets try loading the a file of Type A
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            FUCntrl = new FileUCntrl("EExchange", ModuleType.A);
            MainPanel.Controls.Add(FUCntrl);
        }
    }


***********FileUserControl**************
    public partial class FileUCntrl : UserControl
    {
        public ModuleA ModA = null;
        public ModuleA ModB = null;
        public Form1.ModuleType MType;
        public string FName = string.Empty;

        public FileUCntrl(string fName, Form1.ModuleType type)
        {
            InitializeComponent();
            FName = fName;
            MType = type;
        }

        private void LoadBut_Click(object sender, EventArgs e)
        {
            switch (MType)
            {
                case Form1.ModuleType.A:
                    ModA = new ModuleA(FName, false);
                    FilePanel.Controls.Add(UA);
                    break;

                case Form1.ModuleType.B:
                    ModB = new ModuleB(FName, false);
                    FilePanel.Controls.Add(UB);
            }
        }
    }


*********ModuleA****************
  public partial class ModuleA : UserControl
    {
        public string FName = string.Empty;

        public ModuleA(string fName, bool B)
        {
            InitializeComponent();
            FName = fName;
        }

        private void button1_Click(object sender, EventArgs e)
        { 
            Console.WriteLine(">>" + FName);
        }
    }

Open in new window

0
 
San24Author Commented:
@Keeghi - Yes definitely interested. I think having a loosely coupled UI and Logic might be the way to go, I`m not sure how to go about it and what good a approach is. An example might be of great help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.