Insert data from two forms using SP

muleo

Member
Joined
May 24, 2020
Messages
7
Programming Experience
1-3
Hi everyone.
I am trying to insert data from two forms (winform) into SQL. The form 1 contains some textbox and a datagridview , and Form2 contains two textboxes. When the user click button"btnform2", the form two is opened but the form 1 still remains opened. Now i want when user click the button save(form2) , the data to be saved into sql from two forms.
I created a class
C#:
public class arka_data
{
public int NR { get; set; }
public int BARKODI { get; set; }
public string EMERTIMI { get; set; }
public int SASIA { get; set; }
public float CMIMI { get; set; }
public float TVSH { get; set; }
public float TOTAL { get; set; }
public float NENTOTALI { get; set; }
public float ZBRITJA { get; set; }
public float TOTALI { get; set; }
public DateTime KOHA { get; set; }
public string KASIERI { get; set; }
public string KLIENTI { get; set; }
public float VLERAETVSH { get; set; }
public float VLERAPATVSH { get; set; }
public int NRATIKUJVE { get; set; }
public float TOTALIPCS { get; set; }
            public float VLERATVSHTOTAL { get; set; }
        }
And a method using the upper class to collect data
C#:
   public void mbushe(string[] args)
{
for (int i = 0; i < dataTable.Rows.Count; i++)
{
arka_data ad = new arka_data();
ad.NR = int.Parse(txtnrfatures.Text);
ad.VLERATVSHTOTAL = float.Parse(textBox1.Text);
ad.BARKODI = int.Parse(dataTable.Rows[0].ToString());
ad.SASIA = int.Parse(dataTable.Rows[2].ToString());
ad.CMIMI = int.Parse(dataTable.Rows[3].ToString());
ad.TVSH = int.Parse(dataTable.Rows[4].ToString());
ad.NENTOTALI = float.Parse(txttotali.Text);
ad.ZBRITJA = float.Parse(txtzbritja.Text);
ad.TOTALI = float.Parse(totali.Text);
ad.KOHA = DateTime.Now;
ad.KASIERI = lbluser.Text;
ad.KLIENTI = cmbklienti.Text;
ad.VLERAETVSH = float.Parse(dataTable.Rows[7].ToString());
ad.VLERAPATVSH = float.Parse(dataTable.Rows[6].ToString());
ad.NRATIKUJVE = int.Parse(lblnumri.Text);
ad.TOTALIPCS = float.Parse(dataTable.Rows[5].ToString());
//and finally
                    Program.dta.Add(ad);
                }
            }
But in form 2 , there are not passing data from form 1 .
The code i am using to store data

C#:
  private void button1_Click(object sender, EventArgs e)
        {
            arka_data ad = new arka_data();
string faturimi = "Metoda e pagesese" + " "+ "KESH;" +"Paguar"+ txtpaguar.Text + " "+ "Kusuri"+ textBox3.Text;
con.Open();
SqlCommand cmd = new SqlCommand("insertfaturimi", con);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@nrfatures", ad.NR));
cmd.Parameters.Add(new SqlParameter("@klienti", ad.KLIENTI));
cmd.Parameters.Add(new SqlParameter("@pagesa", faturimi));
cmd.Parameters.Add(new SqlParameter("@nentotali", ad.NENTOTALI));
cmd.Parameters.Add(new SqlParameter("@zbritje", ad.ZBRITJA));
cmd.Parameters.Add(new SqlParameter("@totali", ad.TOTALI));
cmd.Parameters.Add(new SqlParameter("@vleratvsh", ad.VLERATVSHTOTAL));
cmd.Parameters.Add(new SqlParameter("@nrartikujve", ad.NRATIKUJVE));
cmd.Parameters.Add(new SqlParameter("@kasieri", ad.KASIERI));
cmd.Parameters.Add(new SqlParameter("@koha", DateTime.Now));
cmd.Parameters.Add(new SqlParameter("@barkodi", ad.BARKODI));
cmd.Parameters.Add(new SqlParameter("@emertimi", ad.EMERTIMI));
cmd.Parameters.Add(new SqlParameter("@sasia", ad.SASIA));
cmd.Parameters.Add(new SqlParameter("@tvsh", ad.TVSH));
cmd.Parameters.Add(new SqlParameter("@cmimi", ad.CMIMI));
cmd.Parameters.Add(new SqlParameter("@totalipcs", ad.TOTALIPCS));
cmd.Parameters.Add(new SqlParameter("@vlerapatvshpcs", ad.VLERAPATVSH));
cmd.Parameters.Add(new SqlParameter("@vleraetvshpcs", ad.VLERAETVSH));
cmd.ExecuteNonQuery();
}

If someone could help me about where i am missing something, that don't make the code work.
Thanks to everyone!
 
Last edited by a moderator:

Skydiver

Staff member
Joined
Apr 6, 2019
Messages
1,406
Location
Virginia Beach, VA
Programming Experience
10+
It looks to me that part of the issue here is that the OP is writing code in the classic WinForms style where the the View (e.g. the Forms controls) is the Model, instead of the View only reflecting the the state of the Model. If such a separation were made it would be as simple as the following pseudo code that uses constructor dependency injection:

Code:
class Program
{
    public static void Main()
    {
        var dataModel = new DataModel();
        Application.Run(new MainForm(dataModel));
    }
}

class MainForm : Form
{
    DataModel _dataModel;

    public MainForm(DataModel dataModel)
    {
         _dataModel = dataModel;
    }

    protected override void Load(EventArgs e)
    {
        CopyDataModelToFormControls();
    }

    void btnOpenChildForm_Click(object sender, EventArgs e)
    {
        CopyFormControlsToDataModel();

        var childForm = new ChildForm(_dataModel);
        childForm.ShowDialog();
    }

    void CopyDataModelToFormControls()
    {
        :
    }

    void CopyFormControlsToDataModel()
    {
        :
    }
}

class ChildForm : Form
{
    DataModel _dataModel;

    public ChildForm(DataModel dataModel)
    {
         _dataModel = dataModel;
    }

    protected override void Load(EventArgs e)
    {
        CopyDataModelToFormControls();
    }

    void btnSave_Click(object sender, EventArgs e)
    {
        CopyFromControlsToDataModel();

        DataAccessLayer.Save(_dataModel);    
    }

    void CopyDataModelToFormControls()
    {
        :
    }

    void CopyFormControlsToDataModel()
    {
        :
    }
}
Be warned that if you decide to use constructor dependency injection, the Windows Forms Designer will throw a major fit because it was never written with modern object oriented programming in mind (e.g. no constructor dependency injection; no inheritance; etc.) You will have to use property dependency injection instead of constructor dependency injection if you are married to the WinForms designer.
 

muleo

Member
Joined
May 24, 2020
Messages
7
Programming Experience
1-3
Also I forget to put one line of code on the question. On the end part of method mbushe is a line of code: Program.dta.Add(ad). dta is a static list declared on Program.cs
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,988
Location
Sydney, Australia
Programming Experience
10+
Yes it's supposed to close when the insertion is done
Then I would suggest that you're gong about this in the wrong way. Generally speaking, two objects should not both know about the other. That is pretty much always the case for forms. In this case, your second form should not know anything about the first form. The second form should have one job: gather the user input and make it available. That means that it should have public properties that expose the data in the TextBoxes and that is ALL it does. That might look like this:
C#:
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public string TextBox1Text => textBox1.Text;

        public string TextBox2Text => textBox2.Text;
    }
}
Form1 is then responsible for everything else. When it needs the data from Form2, it creates an instance and displays it by calling ShowDialog. When the dialogue closes, ShowDialog returns and Form1 can get those property values and pass them to the database along with data from its own control(s). Form2 neither knows nor cares what that data was for.
 

muleo

Member
Joined
May 24, 2020
Messages
7
Programming Experience
1-3
Then I would suggest that you're gong about this in the wrong way. Generally speaking, two objects should not both know about the other. That is pretty much always the case for forms. In this case, your second form should not know anything about the first form. The second form should have one job: gather the user input and make it available. That means that it should have public properties that expose the data in the TextBoxes and that is ALL it does. That might look like this:
C#:
using System.Windows.Forms;

namespace WindowsFormsApp1
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
        }

        public string TextBox1Text => textBox1.Text;

        public string TextBox2Text => textBox2.Text;
    }
}
Form1 is then responsible for everything else. When it needs the data from Form2, it creates an instance and displays it by calling ShowDialog. When the dialogue closes, ShowDialog returns and Form1 can get those property values and pass them to the database along with data from its own control(s). Form2 neither knows nor cares what that data was for.
Can i use a class to handle this data from form2 or in what way can i handle these data. Thnkas again!
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,988
Location
Sydney, Australia
Programming Experience
10+
Not sure why you need an extra class. Getting the data from properties in Form2 is the same as getting data from properties of controls on Form1. You certainly can use an extra class if you want to but if you're not already doing so for Form1 then what exactly do you think you're achieving? If you want to have Form1 create an object that you pass to Form2 via a property or constructor and then have Form2 populate, go right ahead. Form2 still has no specific dependency on Form1 if you do that so there's no tight coupling.
 

muleo

Member
Joined
May 24, 2020
Messages
7
Programming Experience
1-3
Not sure why you need an extra class. Getting the data from properties in Form2 is the same as getting data from properties of controls on Form1. You certainly can use an extra class if you want to but if you're not already doing so for Form1 then what exactly do you think you're achieving? If you want to have Form1 create an object that you pass to Form2 via a property or constructor and then have Form2 populate, go right ahead. Form2 still has no specific dependency on Form1 if you do that so there's no tight coupling.
The reason that i am thinking to use class is because i am thinking to create an intermediate form between form 1 and form 2. The intermediate form will be useful for user (seller )to choose the method of payment (credit or cassh) and depend of the choise the relevant form will open. For example if the seller chose cash , the form_cash will open where seller will give the detail( paid, change etc) . So maybe the class could hold the payment data , and use these data on form 1 during the process of insertion
 

muleo

Member
Joined
May 24, 2020
Messages
7
Programming Experience
1-3
Or should i store the paymement data of form3 somewhere else( for example on a list or somewhere else)
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
2,988
Location
Sydney, Australia
Programming Experience
10+
The first form manages the whole thing. The first form shows the second form to select the payment method. The first form gets the payment method from the second form and then opens the third form based on that payment method. The first form then gets the data from the third form and then it saves the data as appropriate.
 
Top Bottom