As others have said, once you see that a form is just a class, then anything
is possible and you will see many ways to do these kind of things. For
example, to have bidirectional links between two forms (say the MainForm and
a LogForm) can be done a couple ways.
1) MainForm - As you probably want to keep the log form open but hidden all
the time, you can add a private var to your declaration section in MainForm.
Then in the load method, create an instance of the LogForm for the rest of
MainForm (or others) to use. Now add a Public property (or public method)
to LogForm that returns a ref (i.e. getter) to the richtextbox on the
LogForm. Now MainForm has everything it needs. It has a ref to LogForm and
can "see" the richtextbox to append some text. It is probably better to use
a Public method in LogForm to do this as you "contain" more logic in LogForm
that way and handle errors, returns and don't expose your raw control to
MainForm which could help reduce problems along the way.
2) So now you can start LogForm from MainFrom and append text as you need.
But what if LogForm needs to check a public field or public property in
MainForm to see if something is set or not (i.e. an AllowClearLog flag or
something else set in an options dialog.) Or maybe it too needs to append
some text to a richtextbox in main after it does something usefull. LogForm
is constructed and running, but it does not now anything about MainForm and
has no reference to it. For this, standard class constructors can help. As
a Form is first a class like any other, you can instantiate a form using a
constructor and passing in values or ref types. This is what we need and
how LogForm will know how to ref back to MainForm to see Public Properties
or public fields or public methods. So in MainForm, when you load the
instance of the LogForm, do it this way "logForm = new LogForm(this);".
This passes the ref to MainForm to the LogForm(MainForm mainForm)
constructor. You need to add/change the LogForm(MainForm mainForm)
constructor in LogForm. Remember to use "MainForm" type and not "Form" or
"Object" as you will have to down-cast Form to MainForm anyway in your code
to "see" MainForm's public properties.
Now MainForm can see LogForm and visa-versa. When you see the linkages, you
can use this for many kinds of inter-form/class communications. Here is an
example:
MainForm
======
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace ReferenceBetweenForms
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.Button btnShowLog;
private System.Windows.Forms.RichTextBox richTextBox1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private LogForm logForm; //private var to hold common reference to
LogForm.
public MainForm()
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.btnShowLog = new System.Windows.Forms.Button();
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.SuspendLayout();
//
// btnShowLog
//
this.btnShowLog.Location = new System.Drawing.Point(224, 232);
this.btnShowLog.Name = "btnShowLog";
this.btnShowLog.TabIndex = 0;
this.btnShowLog.Text = "Show Log";
this.btnShowLog.Click += new System.EventHandler(this.btnShowLog_Click);
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(24, 32);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(240, 152);
this.richTextBox1.TabIndex = 1;
this.richTextBox1.Text = "";
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(320, 273);
this.Controls.Add(this.richTextBox1);
this.Controls.Add(this.btnShowLog);
this.Name = "MainForm";
this.Text = "Main";
this.Load += new System.EventHandler(this.MainForm_Load);
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new MainForm());
}
private void MainForm_Load(object sender, System.EventArgs e)
{
logForm = new LogForm(this);
}
private void btnShowLog_Click(object sender, System.EventArgs e)
{
logForm.LogFormRichText.AppendText("Main Form Showed LogForm and appended
this text.\n");
logForm.LogThis("Main Form appended this text using Public Method.\n");
logForm.Show();
}
public RichTextBox MainFormRichText
{
get { return this.richTextBox1; }
}
} //End MainForm Class
}
LogForm
===========
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
namespace ReferenceBetweenForms
{
/// <summary>
/// Summary description for Form2.
/// </summary>
public class LogForm : System.Windows.Forms.Form
{
private System.Windows.Forms.RichTextBox richTextBox1;
private System.Windows.Forms.TextBox tbParent;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button btnOK;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
private System.Windows.Forms.Button btnClearLog;
private MainForm mainForm;
public LogForm(MainForm parentForm)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();
//
// TODO: Add any constructor code after InitializeComponent call
//
mainForm = parentForm; //Set private var "mainForm" so logger always has
reference to mainform.
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.richTextBox1 = new System.Windows.Forms.RichTextBox();
this.tbParent = new System.Windows.Forms.TextBox();
this.label1 = new System.Windows.Forms.Label();
this.btnOK = new System.Windows.Forms.Button();
this.btnClearLog = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// richTextBox1
//
this.richTextBox1.Location = new System.Drawing.Point(8, 40);
this.richTextBox1.Name = "richTextBox1";
this.richTextBox1.Size = new System.Drawing.Size(272, 168);
this.richTextBox1.TabIndex = 0;
this.richTextBox1.Text = "";
//
// tbParent
//
this.tbParent.Location = new System.Drawing.Point(64, 8);
this.tbParent.Name = "tbParent";
this.tbParent.TabIndex = 1;
this.tbParent.Text = "";
//
// label1
//
this.label1.Location = new System.Drawing.Point(16, 8);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(48, 23);
this.label1.TabIndex = 2;
this.label1.Text = "Parent:";
//
// btnOK
//
this.btnOK.Location = new System.Drawing.Point(200, 248);
this.btnOK.Name = "btnOK";
this.btnOK.TabIndex = 3;
this.btnOK.Text = "OK";
this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
//
// btnClearLog
//
this.btnClearLog.Location = new System.Drawing.Point(200, 216);
this.btnClearLog.Name = "btnClearLog";
this.btnClearLog.TabIndex = 4;
this.btnClearLog.Text = "Clear";
this.btnClearLog.Click += new
System.EventHandler(this.btnClearLog_Click);
//
// LogForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 277);
this.Controls.Add(this.btnClearLog);
this.Controls.Add(this.btnOK);
this.Controls.Add(this.label1);
this.Controls.Add(this.tbParent);
this.Controls.Add(this.richTextBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Name = "LogForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Log";
this.Closing += new
System.ComponentModel.CancelEventHandler(this.LogForm_Closing);
this.Load += new System.EventHandler(this.LogForm_Load);
this.ResumeLayout(false);
}
#endregion
private void btnOK_Click(object sender, System.EventArgs e)
{
this.Hide();
}
private void LogForm_Load(object sender, System.EventArgs e)
{
mainForm.MainFormRichText.AppendText("LogForm was loaded and appended
this text to MainForm using reference passed to LogForm() constructor.");
this.tbParent.Text = mainForm.Name;
}
public void LogThis(string logText)
{
//One option is to use a public method to log text.
//This is probably preferred as you "contain" all append and error
//logic in the class where it belongs (i.e. the LogForm.)
this.richTextBox1.AppendText(logText);
}
private void btnClearLog_Click(object sender, System.EventArgs e)
{
this.richTextBox1.Clear();
}
private void LogForm_Closing(object sender,
System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
this.Hide();
}
public RichTextBox LogFormRichText
{
//Another option is to use a public Property to return a ref. to
//the RichTextBox and let MainForm logic append.
get { return this.richTextBox1; }
}
}
}
HTH