-2

I have this situation: in my form Order there's a combobox with many products inside. it is expected that the user could add products to the combobox to use in Order, but this is made via another form called ProductAdd, basically made with a textbox where the user types the name of the product and it's added with a button. Since I can't have access to the combobox in the Order form when I'm in the ProductAdd form, I made a method in Order which add into the combobox the product passed.

The string is not added to the combobox in the other form.

This is the method in Order to operate in its combobox

public void addProductInCbb(string newProduct)
  {
      cbbProdotti.Items.Add(newProduct);
  }

This is the method in the other form ProductAdd to add the string in my cbb

private void btnConfirmNewProduct_Click(object sender, EventArgs e)
        {   
            Order o = new Order(new Form1()); //that's because I think I need an instance of Order to call the method... is that correct?
            String newProduct= txtNewProduct.Text; //get product string from txt

            //boring checks to say if product already exists
            bool found = false;
            ArrayList products= o.getProducts();

            foreach(String product in products)
            {
                if (product.Equals(newProduct)) found = true;
            }
            if (!found)
            {
                o.addProductInCbb(newProduct); //method call from Order
                MessageBox.Show("Success!","", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }  
            else MessageBox.Show("Product already exists!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                
        }

-EDIT- I made the weird "Order o = new Order(new Form1())" constructor because: to call addProductInCbb(string) I ned an Order instance, BUT in turn, the Order constructor ned a Form1 parameter, because when the Order is completed, a PDF is created with all the data from both form1 and Order form... May this cause my issue?

AleMaffe
  • 49
  • 1
  • 7
  • For this [in the Top 5 recurrent question](https://www.google.com/search?q=stack+overflow+c%23+from+another+form) you can use according to your [opinion](https://stackoverflow.com/search?q=%5Bc%23%5D+from+another+form): singleton forms, static data members, events, static run method pattern, constructor with parameters, and so on... –  Aug 08 '21 at 19:47
  • @OlivierRogier But in fact, I made the method `addProductInCbb(newProduct)` which is a sort of "set" or something like that. Why it doesn't work then? – AleMaffe Aug 08 '21 at 19:53
  • Personally I create all of my single instance forms as singletons. And when I need multiple instance forms, I use technologies mentionned in duplicate depending on the situation. About your code, I found it weird and I'm having trouble figuring out what you're trying to do. You need to study conventional models and choose the one that best suits your needs: basically, a static run method or passing the reference of the current form or desired control or data member to the newly created one constructor, or subscribe to an event of the latter. Using singletons makes interop clean if suitable. –  Aug 08 '21 at 19:58
  • @OlivierRogier yeah in fact that `new Order(new Form1())` didn't convinced me from the beginning... but I made this because: to call `addProductInCbb(string)` I ned an `Order` instance, BUT in turn, the `Order` constructor ned a `Form1` parameter, because when the Order is completed, a PDF is created with all the data from both form1 and Order form... – AleMaffe Aug 08 '21 at 20:04
  • 1
    You need an instance of the form and cannot close the form. See my two form project : https://stackoverflow.com/questions/34975508/reach-control-from-another-page-asp-net – jdweng Aug 08 '21 at 20:19
  • I'm instancing creating the new object... Where am I wrong?? I can't understand, all your examples are basically made using gets, but in order to use Gets you Need an instance, and I created It.. so what else? – AleMaffe Aug 09 '21 at 11:54

1 Answers1

1

Here are a set of steps to follow to learn, without disturbing your existing code:

  • Make a new winforms project
  • Ensure it has 2 forms (form1, form2)
  • On the first form put a combobox (comboBox1) and a button (button1)
  • On the second form, put two text box (textBox1, textbox2) and a button (button1)
  • In the constructor of form1, after IinitializeComponent, put:

    var dt = new DataTable();
    dt.Columns.Add("disp");
    dt.Columns.Add("val");
    dt.Rows.Add("first", "1");
    dt.Rows.Add("second", "2");

    comboBox1.DisplayMember = "disp";
    comboBox1.ValueMember = "disp";
    comboBox1.DataSource = dt;

    new Form2(dt).Show();

  • Double click the button on form 1 and put a code in the event handler. This is just to demo some other thing, not needed for passing data between forms:
    MessageBox.Show(comboBox1.SelectedValue.ToString());
  • Modify the constructor of Form2 to accept a DataTable parameter; store the parameter into a class level variable
    private DataTable _dt;

    public Form2(DataTable dt){
      _dt = dt;
    }

  • Double click the button of form2 and put a handler code:
    _dt.Rows.Add(textBox1.Text, textBox2.Text);
  • Run the app. You'll notice that whatever you write in tb1 and tb2 on form2, is added to the combo when you click the button. Clicking the button on form1 shows e.g. "1" when "first" is selected in the combo. This is how you show the user some nice string value, but you have some other value, like an int ID, behind it

WHat's happening is: form2 adds data into the shared datatable that both form2 and form1's combo know about (the combo uses the datatable as its data source). When rows are added the binding mechanism ensures that the databound control is notified and it will refresh itself.

It doesn't have to be a datatable, it can be any data containing class that you share, but datatables are fairly convenient for data binding in windows forms apps

Caius Jard
  • 72,509
  • 5
  • 49
  • 80
  • THTAT'S the point: HOW could I use objects which are visible to both Form1 AND Form2 without re-creating an instance of Form2 in Form1?? So, Why your DataTable is visible to Form1 and Form2?? How is this possible? – AleMaffe Nov 07 '21 at 14:07
  • 1
    Form1 built the datatable and passed it to form2 when it created it: `new Form2(dt).Show();` - form2's constructor captured it (see the bullet point starting *Modify the constructor of Form2*) and stashed it in a class level variable, but it's the same datatable as form1 has access to - 2 references to the same object in memory – Caius Jard Nov 07 '21 at 17:38
  • 1
    *without re-creating an instance of Form2 in Form1?* well.. Form1 has access to Form2, so you could even make some public method on form2 that accepts a datatable and holds onto it, then that can become the way form1 shares data to form2 – Caius Jard Nov 07 '21 at 17:39
  • Ok I think I understand... So basically to make some objects visible to other form I have to pass them in the constructor of the other one when I create it... but is this the only way? I tried and it works but.. If I have to pass 50 objects I have to use 50 parameters in the constructor? Isn't it a bit weird? Isn't there a more technological-automatic-"write once run anywhere" method? – AleMaffe Nov 08 '21 at 18:56
  • 1
    I can only answer that if I can see how you've done it at the moment. I'm quite certain that *If I have to pass 50 objects I have to use 50 parameters in the constructor* is slightly misguided though; we can always pass only one thing to achieve what we want – Caius Jard Nov 08 '21 at 18:58
  • yeah yeah for example an array instead of 50 TextBox, for example, is that what you mean? But let's suppose I have 50 different type of objects in my Form1, and I want to make them all visible and editable in Form2, or worse, in ALL the solution's forms... How could I do this? – AleMaffe Nov 08 '21 at 19:02
  • 1
    Erm.. You'd probably encapsulate them into a UserControl that you could put wherever you wanted - i.e. write your own control that is this composition of 50 textboxes etc – Caius Jard Nov 08 '21 at 19:05
  • I'll do it. Now i know how to use it. It's strange professors don't teach it in school, basically it's the main thing to know in order to work on C#, otherwise it'll not be an obj oriented language. Thank you so much! – AleMaffe Nov 08 '21 at 19:09
  • 1
    I think it's entirely possible it was taught, just not in a form that you'd immediately recognize. A user control isn't really anything more than any other class, like Person is a bunch of strings (name, address, ssn), ints (age, height, weight), etc – Caius Jard Nov 08 '21 at 19:10