简体   繁体   中英

Passing data between forms c# delegate

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();

    }

}

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.

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();
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM