Sharing values between forms

G

Guest

Hello,

Please pardon my ignorance as this is something I should know, but I'm a
little unclear. I have an MDI based app. It is setup so the user opens a file
and the main child form is created. Once that is opened one (or more)
properties forms can be opened. What is the best method for sharing data
between the properties forms and the main child form? I need to alert the
main child form when a value is modified in a properties form so I can modify
the contents of the child form.

Hopefully I'm making sense. Thanks for any help, I really appreciate it.

Thanks,
Nick
 
D

D. Yates

Nick,
What is the best method for sharing data between the properties
forms and the main child form?

1. Store the data in a class that is passed to each of the forms upon
creation.
2. Create events that can be fired when the properties are changed.
3. Create an instance of the class when your main form is created and tie
the events to method within the main child form, so that when anyone changes
a property the main child form is notified.

Using a separate class also prevents the forms from having to know about
each other, which in most cases is a good thing.

Dave
 
T

TerryFei

Hi Nick,
Welcome to MSDN Newsgroup!

From my experience, since all the forms in MDI are in a single thread, if
we want to share data between these forms, we could use global variable to
achieve the goal.
If we want to notify forms that relevant data has been modified, we could
post/send message or use events & delegates to do it.

I also browse some articles from internet and hope it's helpful for you.
Title: A C# Framework for Interprocess Synchronization and Communication
URL: http://www.codeproject.com/csharp/csthreadmsg.asp

Title: DevGlobalCache - A way to Cache and Share data between processes
URL: http://www.codeproject.com/dotnet/globalcache.asp

I hope the above information is helpful for you. If you have any questions
or concerns, please feel free to let me know. I am looking forward to
hearing from you. Thanks!

Best Regards,

Terry Fei [MSFT]
Microsoft Community Support
Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
G

Guest

Dave,

Thanks a lot for your help. I've got everything covered that you mentioned,
except I'm not sure how to notify the main child form when a property
changes. I know I need to use events/delegates, but I've never used them
before and can't quite get a good handle on them.

Let's say my properties form has only a textbox. When the textbox changes I
want something in the main child form to change. Do you happen to know where
I can find a sample similar to that?

Thanks a lot for your help, I really appreciate it.

Thanks,
Nick
 
T

TerryFei

Hi Nick,
Tnanks for your feedback!

Based on your description, we could follow next steps to achieve the goal,
1.Write Event handler in main child form class. For example, if the main
child form focus on TextChanged event in textbox, we could add the
following event handler code in your main child form class,
void textBox1_TextChanged(object sender, System.EventArgs e)
{
}

2.Create a delegate to associate the above handler with TextChanged event.
Please refer to the following code,
textBox1.TextChanged += new System.EventHandler(textBox1_TextChanged);
Then if the text in textbox changed, textBox1_TextChanged method in main
child form class will be invoked.

I also browse some articles from internet and hope it's helpful for you.
Title: Step by Step: Event handling in C#
URL: http://www.codeproject.com/csharp/StepByStepEventsInCS.asp

Title: Events and Delegates simplified
URL: http://www.codeproject.com/csharp/events.asp

If you have any questions, please don't hesitate to let me know. Thanks and
have a nice day!

Best Regards,

Terry Fei [MSFT]
Microsoft Community Support
Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
G

Guest

Hi Terry,

Got it working! Thanks a lot for your (and Dave and J. Verdrengh) help, I
really appreciate it.

Thanks,
Nick
 
T

TerryFei

Hi Nick,

I am glad to know the problem has been resolved. : )
It's my pleasure to work with you.

Best Regards,

Terry Fei [MSFT]
Microsoft Community Support
Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
G

Guest

Terry,

I wonder if I could ask one more question. I've got it setup to work when I
only have one child window open. When I open a second child window and change
a property it changes both child windows. How can I only change the active
window?

Thanks,
Nick
 
T

TerryFei

Hi Nick,
Nice to see you again! : )
I am not very clear to it. Would you provide me a sample to reproduce it. I
think it'll help us get closer to this issue.

If your meaning is that the same event for multiple objects (all child
windows)to be handled by the same method, such as multiple buttons with the
same handler. And you want to know which genuine object in handler is. You
could use the sender argument to determine which object fired the event:
private void button_Click(object sender, System.EventArgs e) {
Button button = sender as Button;
MessageBox.Show(button.Text + " was clicked");
}

If you have any questions, please don't hesitate to let me know. Thanks and
have a nice day!

Best Regards,

Terry Fei [MSFT]
Microsoft Community Support
Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
G

Guest

Hi Terry,

Here is a simple example. I tried to make it as short as I could.

//*************************************

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplication4
{
/// <summary>
/// Summary description for Form1.
/// </summary>
public class MainForm : System.Windows.Forms.Form
{
private System.Windows.Forms.MainMenu mainMenu1;
private System.Windows.Forms.MenuItem menuItem1;
private System.Windows.Forms.MenuItem menuItem2;

private PropertiesForm propForm;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

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.mainMenu1 = new System.Windows.Forms.MainMenu();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.menuItem2 = new System.Windows.Forms.MenuItem();
//
// mainMenu1
//
this.mainMenu1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem1});
//
// menuItem1
//
this.menuItem1.Index = 0;
this.menuItem1.MenuItems.AddRange(new System.Windows.Forms.MenuItem[] {
this.menuItem2});
this.menuItem1.Text = "File";
//
// menuItem2
//
this.menuItem2.Index = 0;
this.menuItem2.Text = "Open forms";
this.menuItem2.Click += new System.EventHandler(this.menuItem2_Click);
//
// MainForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.IsMdiContainer = true;
this.Menu = this.mainMenu1;
this.Name = "MainForm";
this.Text = "MainForm";
this.MdiChildActivate += new
System.EventHandler(this.MainForm_MdiChildActivate);

}
#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.Run(new MainForm());
}

private void menuItem2_Click(object sender, System.EventArgs e)
{
if (propForm==null)
{
propForm=new PropertiesForm();
propForm.Show();
}

ChildForm c1=new ChildForm("abc");
c1.Show();
c1.MdiParent=this;


ChildForm c2=new ChildForm("123");
c2.Show();
c2.MdiParent=this;


this.propForm.OnTextChange+=new
ChangeHandler(((ChildForm)this.ActiveMdiChild).TextHasChanged);
}

private void MainForm_MdiChildActivate(object sender, System.EventArgs e)
{
}
}

public class ChildForm : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;

public ChildForm(string s)
{
//
// Required for Windows Form Designer support
//
InitializeComponent();

//
// TODO: Add any constructor code after InitializeComponent call
//
textBox1.Text=s;
}

/// <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.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(48, 48);
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(192, 20);
this.textBox1.TabIndex = 1;
this.textBox1.Text = "";
//
// ChildForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.textBox1);
this.Name = "ChildForm";
this.Text = "ChildForm";
this.ResumeLayout(false);

}
#endregion

public void TextHasChanged(object sender, System.EventArgs e)
{
this.textBox1.Text=((TextBox)sender).Text;
}

}

public delegate void ChangeHandler(object sender, EventArgs e);



/// <summary>
/// Summary description for PropertiesForm.
/// </summary>
public class PropertiesForm : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;


public event ChangeHandler OnTextChange;

public PropertiesForm()
{
//
// 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.textBox1 = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(48, 48);
this.textBox1.Name = "textBox1";
this.textBox1.Size = new System.Drawing.Size(192, 20);
this.textBox1.TabIndex = 0;
this.textBox1.Text = "";
this.textBox1.TextChanged += new
System.EventHandler(this.textBox1_TextChanged);
//
// PropertiesForm
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.textBox1);
this.Name = "PropertiesForm";
this.Text = "PropertiesForm";
this.ResumeLayout(false);

}
#endregion

private void textBox1_TextChanged(object sender, System.EventArgs e)
{
if (OnTextChange!=null)
OnTextChange(sender, e);
}
}
}
//*********************************

"TerryFei" said:
Hi Nick,
Nice to see you again! : )
I am not very clear to it. Would you provide me a sample to reproduce it. I
think it'll help us get closer to this issue.

If your meaning is that the same event for multiple objects (all child
windows)to be handled by the same method, such as multiple buttons with the
same handler. And you want to know which genuine object in handler is. You
could use the sender argument to determine which object fired the event:
private void button_Click(object sender, System.EventArgs e) {
Button button = sender as Button;
MessageBox.Show(button.Text + " was clicked");
}

If you have any questions, please don't hesitate to let me know. Thanks and
have a nice day!

Best Regards,

Terry Fei [MSFT]
Microsoft Community Support
Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
T

TerryFei

Hi Nick,
Thanks for your detailed information to help me clear to this issue.

In this scenario, I suggest you could confirm whether or not a ChildForm is
an active window at first in TextHasChanged handler. If yes, change its
property value. If not, do nothing. Please refer to the following code,
public void TextHasChanged(object sender, System.EventArgs e)
{
if (this == this.MdiParent.ActiveMdiChild)
{
this.textBox1.Text=((TextBox)sender).Text;
}
}

I hope the above information is helpful for you. Thanks for your
understanding!

Best Regards,

Terry Fei [MSFT]
Microsoft Community Support
Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top