2

I have two forms (Form1 and Form2) that I would like to pass a string of characters between after a process completes on Form1.

On Form1, there is a text box that I would like to update with this string of characters. On Form2, I have a list box that contains the values that will eventually be loaded into this text box on Form1 after every process that completes. Basically what I am trying to do is to queue the next string that will be placed in the text box on Form1.

I have tried the creating a public property in Form2 as seen below:

public string NextString { get { return ListBox1.Items[ListBox1.TopIndex].ToString(); } }

Then, in Form1:

Form2 frm = new Form2();
string next = frm.NextString;
TextBox1.Text = next;

And presto. Except not. This was not working for me, unfortunately. I did some research and saw that this method was not quite the best practice and read that using event handlers was the more practical approach. So I researched those. I know that I have to create a new EventArgs class, a new public event, a firing method, how I want to handle the event, and then the handler method in Form1. This post is where I read into that.

I've played around with manipulating the answer to suit my needs:

public class StringEventArgs : EventArgs
{
    public string NextString { get; set; }
    public StringEventArgs(string data)
    {
        NextString = data;
    }
}

A new event:

public event EventHandler<ListEventArgs> NewFileAdded;

This is where I got lost. I'm having a hard time understanding what is going on now. If anyone can help me completed what I am trying to do, I would be very grateful!

Zach Yarid
  • 55
  • 5

2 Answers2

2

There's no need to create your own Args class. You can accomplish this using an Action that Form2 subscribes to.

Something like:

public class Form1
{
    private Form2 _form2;

    public event Action<string> NextStringChanged;

    public class Form1()
    {
       _form2 = new Form2(this);
    }

   private void LongProcess()
   {
      _form2.Show();

      // do long process

     if (NextStringChanged != null)
     {
      NextStringChanged.Invoke(ListBox1.Items[ListBox1.TopIndex].ToString());
     }
   }
}

public class Form2
{
   public class Form2(Form1 form1)
   {
      form1.NextStringChanged += OnNextStringChanged;
   }

   private void OnNextStringChanged(string value)
   {
      // Update WPF user control here
   }
}
d.moncada
  • 16,900
  • 5
  • 53
  • 82
  • I am not sure if this would make a difference in this solution, but the listbox where I'd like to grab the next value is located on Form2. It looks like this might have switched the two. Nevertheless, when I tried to implement this, I got "No overload for 'OnNextStringChanged' matches delegate 'Action' ". Any ideas? – Zach Yarid Oct 07 '17 at 16:40
  • sorry, see update. Note that in Form1, it is now Action – d.moncada Oct 07 '17 at 19:23
  • I think you flipped Form1 and Form2. The listbox is located on Form2. Form2 is the auxiliary form and Form1 is the main form. – Zach Yarid Oct 08 '17 at 03:00
  • @ZachYarid so, you want the value of Form2 to be notified to Form1? Does Form1 have an instance of Form2? – d.moncada Oct 08 '17 at 03:03
0

There are number of ways to pass data between different forms, check this out:

  1. First create the string you want to share in Form2:

public string NextString { get { return ListBox1.Items[ListBox1.TopIndex].ToString(); } }

  1. to access that string use this code:

string Testing = ((Form2)Application.Current.Windows[2]).NextString;

P.S. you may have to use a different index number for Form2 as I'm not sure exactly where it's located in your app.

Dark Templar
  • 1,130
  • 8
  • 10
  • For this, I get Application does not contain a definition for Current. The target .NET framework is 4.6.1, if that helps. – Zach Yarid Oct 07 '17 at 16:42