Reputation: 294
I'm trying to pass data between forms using delegate. I'm using TrackBar and I'd like to send value from trackBar to second form. The problem is that I want to open two forms simultaneously. When I open first Form and when the slider value is change then show Form2 everything works fine. But when I open two forms simultaneosuly then nothing happen. I'll be grateful for any help :)
Program.cs
public class MultiFormContext : ApplicationContext
{
private int openForms;
public MultiFormContext(params Form[] forms)
{
openForms = forms.Length;
foreach (var form in forms)
{
form.FormClosed += (s, args) =>
{
if (System.Threading.Interlocked.Decrement(ref openForms) == 0)
ExitThread();
};
form.Show();
}
}
}
static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MultiFormContext(new Form2(), new Form1()));
}
}
Form1.cs
public delegate void delPassData(TrackBar trackVal);
public partial class Form1 : Form
{
Form2 form2 = new Form2();
public Form1()
{
InitializeComponent();
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
delPassData delegat = new delPassData(form2.someValFromTrackBar);
//form2.Show();
delegat(this.trackBar1);
}
}
Form2.cs
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public void someValFromTrackBar(TrackBar valFromTrackBar)
{
label1.Text = valFromTrackBar.Value.ToString();
}
}
Upvotes: 0
Views: 2899
Reputation: 37066
Your Form1
creates an instance of Form2
. This code creates a different instance of Form2
:
Application.Run(new MultiFormContext(new Form2(), new Form1()));
"For some reason" (as the kids say), you didn't include the code for the version that works, but it looks very much like in the case that fails, Form1
is subscribing to a trackbar event on the wrong instance of Form2
.
There must be only one instance of Form2
, and Form1
must have a reference to it. The most straightforward way to only use the instance of Form2
that Form1
creates:
public partial class Form1 : Form
{
Form2 form2 = new Form2();
public Form2 Form2 { get { return form2; } }
...
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form1 = new Form1();
Application.Run(new MultiFormContext(form1.Form2, form1));
}
S. Petrosov's answer will work as well, but MultiFormContext
should not be responsible for knowing, much less implementing, the details of the relationship between those two forms. It can't do it very well, either: What if you add a second trackbar later, with some other purpose? It'll be a mess. MultiFormContext
is a nice clean general class that does one job well. I recommend keeping it that way.
App
shouldn't have that responsibility either, of course, but at least it's not required in my version to know anything but that there is a relationship.
Upvotes: 2
Reputation: 7706
Here is example how you can do communication between two forms.
In this example I have two forms with TrackBar
and TextBox
. When TrackBar
for one Form is scrolled the second ones TextBox
get text "Modified from Form1" or "Modified from Form1".
using System;
using System.Linq;
using System.Windows.Forms;
namespace WindowsFormsApp6
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var form1 = new Form1();
var form2 = new Form2();
Application.Run(new MultiFormContext(form1, form2));
}
}
public class MultiFormContext : ApplicationContext
{
private int openForms;
public MultiFormContext(Form1 form1, Form2 form2)
{
form1.FormClosed += (s, args) =>
{
if (System.Threading.Interlocked.Decrement(ref openForms) == 0)
ExitThread();
};
form1.Controls.OfType<TrackBar>().First().Scroll += (sender, args) =>
{
form2.Controls.OfType<TextBox>().First().Text = "Modified from Form1";
};
form1.Show();
form2.FormClosed += (s, args) =>
{
if (System.Threading.Interlocked.Decrement(ref openForms) == 0)
ExitThread();
};
form2.Controls.OfType<TrackBar>().First().Scroll += (sender, args) =>
{
form1.Controls.OfType<TextBox>().First().Text = "Modified from Form2";
};
form2.Show();
}
}
}
Upvotes: 1