I was developing a WindowsForm application in C#, with 2 forms. Regardless of what they both did specifically I needed to access values in form2
and send them to form1
and vice versa. For this to happen I found someone talking about constructor overload and it worked for me as I explain in the code.
Form1:
namespace miniDldMngr
{
public partial class Main : Form
{
miniDldMngr.SettingsForm settingsForm; //Instantiate settingsForm
private void settingsToolStripButton_Click(object sender, EventArgs e)
{
settingsForm = new miniDldMngr.SettingsForm(this); //Create handle for Form1
settingsForm.ShowDialog(); //Form properties were changed to act like a dialog
}
Form2:
namespace miniDldMngr
{
public partial class SettingsForm : Form
{
private Main HandleToForm1; //local variable to store handle to Form1
public SettingsForm()
{
InitializeComponent();
}
public SettingsForm(Main frm1Handle) //overloaded constructor with handle to Form1
{
InitializeComponent();
HandleToForm1 = frm1Handle;
txtIni.Text = HandleToForm1.comboLoad.Text; //here's how i access controls on form1 for example, as long as modifiers are public
}
I came across this answer on Stack Overflow and user codesparkle commented:
It's neither scalable nor OOP-like.
Which lead me to believe that it might not have been the best choice to solve my initial issue. (S)He further added:
One approach is to create an event in the class that knows the information which needs to be shown. The form can then register one of its methods as an event handler. Once the information becomes available, the class notifies the Form by calling that handler with an argument containing the displayable information. The beauty of this approach is that the class is decoupled (not dependent on) the implementation of Form. The MVC and MVVM design patterns are other robust ways of doing it.
Now I'm left with some questions:
- What are the implications of the procedure I used?
- Why isn't it an object-oriented approach?
- What would be the best practice to send information back and forth between classes/forms?
- How would you go about creating the event mentioned by codesparkle?
- I don't know anything about MVC or MVVM design patterns, so some links to a structured explanation would be appreciated.
Please consider that I'm very new to programming and I won't understand you if you talk like I know what I am doing. Code examples work wonders with me, since I can test them.
Best Answer
To answer each of your questions:
What are the implications of the procedure I used?
In this instance, you are passing a reference from a parent object (the Main form) to the child object (the Settings form). The result of this is that the Settings form must know a lot of things about the Main form in order to work properly. Some not-so-desirable implications:
Why isn't it an object-oriented approach?
Well, what you are doing is object-oriented, however because you have a child object depending on a parent object, you are going against the Dependency Inversion Principle and are thus causing tight coupling between objects.
When people on SO and other sites talk about how "object oriented" something is, they often are referring to S.O.L.I.D., which are five key principles of object oriented design.
What would be the best practice to send information back and forth between classes/forms?
I think in this instance the easiest way to accomplish this would be to create properties in your Settings form that represent the values that are modified within the settings window.
For example, this code would be in your Settings form:
And this code would be in your Main Form:
It is slightly more code, but now you are free to make as many changes as you want to the main form, and the settingsform won't need to be updated.
There are of course many other approaches you can take, which leads me to your last two questions:
How would you go about creating the event mentioned by codesparkle?
Creating and raising an event is another way to avoid tight coupling between two classes. Notice how the Windows Forms objects, such as ToolStrip are able to call methods in your code (settingsToolStripButton_Click), even though the Windows Forms code is not linked to your code. That is the beauty of events. My opinion is that it is overkill in this situation, since you are showing the form as a Dialog (where you can just read all of the values after the dialog closes), but nonetheless here is an example:
First, you would have code like this in your SettingsForm:
Then, you would have code similar to this in your MainForm:
I don't know anything about MVC or MVVM design patterns, so some links to a structured explanation would be appreciated.
The MVVM pattern is a pattern championed by Microsoft, primarily for use in WPF. You can read a nice description here:
http://msdn.microsoft.com/en-us/magazine/dd419663.aspx
You can use this pattern in Windows Forms, however I wouldn't recommend it, as WPF has more of the basic plumbing complete in order to actually make it work.
Happy coding!