Click here to Skip to main content
15,887,485 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi, I am creating a small application, I have a main window with numerous controls and components on. On a particular section I want to add a new food to a list view. To do this I want a button that when clicked opens up a new window with several textboxes asking for details etc once the details are entered a button would be clicked and the entry added to the list view on the main page.

I have no idea how to do this, I am pretty new to c# and I am really not sure how/if you can pass data from a child back to a parent. Or if this is even the best way of doing it! Any input would be welcomed!

Thanks
Posted

Typically how I do this is create a subclass of Form which has a method that wraps ShowDialog and sets a bunch of properties, which you can then call synchronously from the second form. Something like
partial class FoodEditor : Form {
 // Edit the UI in the designer as normal
 
 public string FoodName { get; private set; }
 public int Calories { get; private set; }

 public DialogResult ShowDialog(IWin32Window owner, string name, int calories){
  foodNameTextBox.Text = FoodName = name;
  caloriesNumericEdit.Value = Calories = calories;
  
  DialogResult res = ShowDialog(owner);
  
  if(res == DialogResult.OK){
   FoodName = foodNameTextBox.Text;
   Calories = caloriesNumericEdit.Value;
  }
  return res;
 }
}


And then you can call it thus:
void ButtonEventHandler(object s, EventArgs e){
 if(DialogResult.OK == foodEditor.ShowDialog(this, "New Item", 1000)){
  // Some code to process the edited result, e.g.
  AddToListBox(foodEditor.FoodName, foodEditor.Calories);
 }
}
 
Share this answer
 
Comments
DanHodgson88 23-Aug-11 12:12pm    
:)Thank you very much fro your reply it was much appreciated
Let's look at this in stages:

1. you design your 'new food item' Form.

2. in response to some action in the main UI you present your 'new food item' form: you have a couple of options here:

a. the MSDN article Richard M. referred you to does not actually use a 'dialog-box' at all in the classic sense of that term; it simply uses 'Show to bring up the new-item Form. Nothing wrong with that. However, if your food-data-entry form is just another Form, then, yes, you can display other Forms in front of it, etc. Perhaps distracting ?

b. if you really want your custom Form to behave like a modal dialog-box, then you can use 'ShowModal' instead of 'Show.' Activity on your Application's main thread will pause until you've closed the modally shown Form.

c. another alternative is to make the food-data-entry Form an 'Owned' Form of the main Form. NewFoodItemForm.Owner = MainForm;
This has the nice side-effect that it guarantees your data-entry Form will remain unobscured by the main Form.

3. now you have your new-food-item Form up, and the user has filled in your fields and you want to get that data back to your main Form. Again, several options:

a. the MSDN article Richard M. referred you to injects a reference to the main Form into the data-entry Form. So the data-entry Form can actually access and add new items to the main Form's ListBox. I personally think this is bass-ackward OO design: imho, a part of a structure should not be passed a reference to the wider scope of the entire structure, and have access to its internals state: tail wags dog !

b. another way is to consider what your data-entry-Form must expose to the application-main-form in order for it to receive the data back. It's very simple:

1. you need to expose the Button on your data-entry Form that when clicked indicates the user commits to making a new Item.

2. you need to expose the content of the text fields the user put data in.

The how of this is pretty easy: you implement public properties with private setters: they might look like this:
C#
public string NewItemText[] { get; private set; }
public Button AddItemButton { get; private set; }
You set the value of the Button property in the data-entry form's constructor.
C#
public Form2()
{
    InitializeComponent();
    AddItemButton = btnAddItem;
}
The private 'setters' for the Properties ensure they can only be changed from within the data-entry-form, while the public 'getters' let anyone access them.

Now, you add an event handler in the data-entry form for the Button's click event, and in that event, package up all your fields into a big string, an array of strings, whatever, and then assign that to the NewItemText property. For example:
C#
private void btnAddItem_Click(object sender, EventArgs e)
{
    // here we'll act as if you just typed in a bunch of stuff in a textbox with multiline enabled
    NewItemText = textBox1.Lines;
}
Ah, okay, now how do we get the event of the user saying 'yes, make me new items,' and the data, to register back in our main Form ?

Since the main Form creates the secondary Form, you can add an event handler to the Button inside the data-entry Form:
C#
private Form2 dataEntryForm;

private void Form1_Load(object sender, EventArgs e)
{
    dataEntryForm = new Form2();
    dataEntryForm.Owner = this;
    // at this point we know that the pubic property 'AddItemButton
    // holds a reference the button that causes changes to be accepted.
    dataEntryForm.AddItemButton.Click += new EventHandler(AddItemButton_Click);
}
So this event handler, the second click event handler for the button on the data-entry Form gives you exactly what you need to grab the data and then do whatever you like ... like close the data-entry Form:
C#
private void AddItemButton_Click(object sender, EventArgs e)
  {
      // your data is in here: dataEntryForm.NewItemText
      foreach(string theData in dataEntryForm.NewItemText)
      {
         // do whatever
      }
      // close the data-entry Form ?: dataEntryForm.Close();

  }

Final thoughts: I believe in such cases the user should have a clearly labeled 'save/commit/write changes' button, and a 'cancel' button. And 'nice touches' are to make sure your data-entry Form doesn't show up in the TaskBar, to position it when it is shown so it doesn't obscure your main Form.

Yes, there are other ways you could get the event and the data back to the main Form: you might have an 'event manager' class that acts as an 'intermediary' between main form and data-entry form, for example.
 
Share this answer
 
v3
Comments
DanHodgson88 23-Aug-11 12:12pm    
That answer is possibly the best reply I have had on this forum since I have joined it. I would like to say a big thank you to you for taking the time out to write this. It is much much appreicated!
BillWoodruff 23-Aug-11 23:19pm    
Thanks, Dan, is is my pleasure to give something back to CP which has given me so much for so many years. best, Bill
You would use a Dialog Box[^] to get the user input and then pass the values from the dialog class into the relevant part of your main form.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900