I'm novice in c# and winforms, my idea is to create a simple app , which contains Form1 like this on image
There is dategridview where I can show data from database table Products(ID is not visible),then when I click on button New, Form2 will open
I want to use same Form2 when I want to edit some of the items, selecting specific row in datagridview and clicking on button Edit(I've managed to do this on 2 different win forms).How can I achieve this ?
This is what I've done so far:
button New
private void toolStripButton1_Click(object sender, EventArgs e)
{
Form2 f2 = new Form2(this);
f2.Show();
}
method PerformRefresh()
public void PerformRefresh()
{
this.productsTableAdapter.Fill(this.dbtestDataSet.products);
this.dataGridView1.Refresh();
}
Form2
Form1 _owner;
public Form2(Form1 owner)
{
InitializeComponent();
_owner = owner;
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form2_FormClosing);
}
private void Form2_Load(object sender, EventArgs e)
{
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
_owner.PerformRefresh();
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
string Name = textBox1.Text;
int Quantity = Int32.Parse(textBox2.Text);
MySqlConnection cnn = new MySqlConnection(Konekcija.cnndbtest);
MySqlCommand cmd = new MySqlCommand("INSERT INTO products (Name,Quantity) VALUES(#name, #quantity)", cnn);
cmd.Parameters.AddWithValue("#name", Name);
cmd.Parameters.AddWithValue("#quantity", Quantity);
try
{
cnn.Open();
cmd.ExecuteNonQuery();
cnn.Close();
}
catch (Exception xcp)
{
MessageBox.Show(xcp.Message);
return;
}
MessageBox.Show("Object has been successfully entered into the database", "Message");
this.Close();
}
then, for button Edit on Form1 I've made class MyProducts , and made object of this class ,which I want to pass to Form2
MyProducts myProducts = new MyProducts();
myProducts.ID = Int32.Parse(dataGridView1.CurrentRow.Cells[0].Value.ToString());
myProducts.Name = dataGridView1.CurrentRow.Cells[1].Value.ToString();
myProducts.Quantity = Int32.Parse(dataGridView1.CurrentRow.Cells[2].Value.ToString());
Now I want to show Form2 clicking on button Edit , and when Form2 is shown, I want to have selected Item properties displayed into 2 textbox controls.
Any idea ?
Thanks in advance.
Give Form2 a public Property of MyProducts and fill the TextBoxes
private MyProducts product;
public MyProducts Product
{
set
{
product = value;
if (product != null)
{
nameTextBox.Text = product.Name;
quantityTextBox.Text = product.Quantity.ToString();
}
}
Then before opening the form for edit pass the MyProducts-Element you wanna edit
private void toolStripButton2_Click(object sender, EventArgs e)
{
MyProducts myProducts = new MyProducts();
myProducts.ID = Int32.Parse(dataGridView1.CurrentRow.Cells[0].Value.ToString());
myProducts.Name = dataGridView1.CurrentRow.Cells[1].Value.ToString();
myProducts.Quantity = Int32.Parse(dataGridView1.CurrentRow.Cells[2].Value.ToString());
Form2 f2 = new Form2(this);
f2.Product = myProducts;
f2.Show();
}
then on safe check if product has value to determine update or insert
private void toolStripButton1_Click(object sender, EventArgs e)
{
string Name = textBox1.Text;
int Quantity = Int32.Parse(textBox2.Text);
if (product != null)
{
//SQL Update command
}
else
{
//SQL Insert command
}
//SQL Execute
}
hope this helps
Related
The goal is to display the text from user input using radio button and combo box. I'm using Visual Studio, by the way.
This is the code from the first window:
private void btn_apply_Click(object sender, EventArgs e)
{
firstName = tbx_firstName.Text;
middleName = tbx_middleName.Text;
lastName = tbx_lastName.Text;
completeName = firstName + " " + middleName + " " + lastName + " ";
gender = lbl_gender.Text;
level = lbl_level.Text;
status = lbl_status.Text;
if (rbtn_male.Checked)
{
lbl_gender.Text = rbtn_male.Text.ToUpper();
}
else
{
lbl_gender.Text = rbtn_female.Text.ToUpper();
}
//Level
if (rbtn_gradeEleven.Checked)
{
lbl_level.Text = rbtn_gradeEleven.Text.ToUpper();
}
else if (rbtn_gradeTwelve.Checked)
{
lbl_level.Text = rbtn_gradeTwelve.Text.ToUpper();
}
else if (rbtn_iST.Checked)
{
lbl_level.Text = rbtn_iST.Text.ToUpper();
}
else if (rbtn_iSM.Checked)
{
lbl_level.Text = rbtn_iSM.Text.ToUpper();
}
else
{
}
//Admission Status
cbx_status.SelectedItem.ToString();
//Form2
this.Hide();
Form2 output = new Form2();
output.Show();
Meanwhile, this is the code for the second window (Result):
private void Form2_Load(object sender, EventArgs e)
{
lbl_displayName.Text = Form1.completeName;
lbl_displayGender.Text = Form1.gender;
lbl_displayLevel.Text = Form1.level;
lbl_displayStatus.Text = Form1.status;
}
Thank you!
when Form2 should display elements from Form1, the former surely has to have a reference to the latter. So start giving Form2 a reference to your Form1-instance, e.g. using a constructor-arg on Form2.
However usually you don't want to pass controls or forms around, but just specific values within those. In your case those are the gender, name the level and the status. So just provide those arguments to Form2, not the entire Form1-instance:
class Form2 : Form
{
private readonly string name; // ...
public Form2(string name, string status, string level, string gender)
{
this.name = name;
// ...
}
}
Now you can easily access those variables within your Load-event:
private void Form2_Load(object sender, EventArgs e)
{
lbl_displayName.Text = this.name;
lbl_displayGender.Text = this.gender;
lbl_displayLevel.Text = this.level;
lbl_displayStatus.Text = this.status;
}
Change:
Form2 output = new Form2();
output.Show();
To:
Form2 output = new Form2();
output.Show(this); // <-- Form1 as the Owner of output
Now in Form2, simply cast .Owner back to Form1:
private void Form2_Load(object sender, EventArgs e)
{
Form1 f1 = (Form1)this.Owner;
lbl_displayName.Text = f1.completeName;
lbl_displayGender.Text = f1.gender;
lbl_displayLevel.Text = f1.level;
lbl_displayStatus.Text = f1.status;
}
Im trying to add data to a listview from another form. I have tired doing it from the same form and that works like it should, but when I try to pass the info between the forms no data gets entered.
Form 1 Contains listview
private void button3_Click(object sender, EventArgs e)
{
newTask form = new newTask();
form.Show();
}
Form 2 Contains form to submit info to listview
public void button1_Click(object sender, EventArgs e)
{
string url = textBox1.Text;
string size = textBox2.Text;
Form1 table = new Form1();
table.listView1.Items.Add(url);
table.listView1.Items.Add(size);
this.Hide();
}
With Form1 table = new Form1(); you are creating new object type Form1 and it doesn't reference to your old form.
What you need to do is change constructor of second form to
private Form1 myFirstForm;
public newTask(Form1 form1)
{
InitializeComponent();
myFirstForm = form1;
}
and your second part of code should then look like this:
public void button1_Click(object sender, EventArgs e)
{
string url = textBox1.Text;
string size = textBox2.Text;
myFirstForm.listView1.Items.Add(url);
myFirstForm.listView1.Items.Add(size);
this.Hide();
}
I got 2 forms, Form1 contains the datagridview and button "add", Form2 contains the textboxs and button "save",
I want to add row and form2 appears when add button is clicked, then save informations from form2 in the datagridview when save button is clicked
this is the code i'm using for both add and save buttons, but when i do, it only saves informations wrote from form1 (save button doesn't do much if not updating datagridview)
private void AddButton_Click(object sender, EventArgs e)
{
Form2 windowAdd = new Form2();
windowAdd.SetDesktopLocation(this.Location.X + this.Size.Width, this.Location.Y);
windowAdd.ShowDialog();
var frm2 = new Form2();
frm2.AddGridViewRows(textName.Text, textDescription.Text, textLocation.Text, textAction.Text);
textName.Focus();
this.stockData.Product.AddProductRow(this.stockData.Product.NewProductRow());
productBindingSource.MoveLast();
}
private void SaveButton_Click(object sender, EventArgs e)
{
productBindingSource.EndEdit();
productTableAdapter.Update(this.stockData.Product);
this.Close();
}
Try this approach.
Form2 could accept some parameters for construction. You will have to resolve the reference to the productBindingSource and productDataAdaptor.
public partial class Form2 : Form
{
private DataRow _theRow;
private bool _isNew;
public Form2(DataRow theRow, bool isNew)
{
InitializeComponent();
_theRow = theRow;
_isNew = isNew;
}
private void Form2_Load(object sender, EventArgs e)
{
textName.Text = _theRow["Name"];
// Etc
}
private void btnSave_Click(object sender, EventArgs e)
{
// This is your add / edit record save button
// Here you would do stuff with your textbox values on form2
// including validation
if (!ValidateChildren()) return;
if (_isNew)
{
// Adding a record
productBindingSource.EndEdit();
productTableAdapter.Update();
}
else
{
// Editing a record
}
this.Close();
}
}
This changes your call in the Form1.Add Button event. I have shown below the way to utilize a using block to show a form.
private void btnAdd_Click(object sender, EventArgs e)
{
DataRow newRow = stockData.Product.NewProductRow();
using (var addForm = new Form2(newRow, true))
{
addForm.StartPosition = FormStartPosition.CenterParent;
addForm.ShowDialog(this);
// Here you could access any public method in Form2
// You could check addForm.DialogResult for the status
}
}
This isn't the best way to do this, but this direction might be a easier way to try...
Hope it helps
I have form1 with datagridview (2 columns with 1 column id,1 column text).
I also have "edit button". When i click "edit button", the text column will show in textbox at form2.
In form2 I have "select button" to edit path and "save button".
How can I pass the edited text in form2 to column datagridview in form1 by press "save button".
Code Edit button in form1 (dgv_sourcefolder is datagridview1) :
private void DGV_sourcefolder_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (DGV_sourcefolder.Columns[e.ColumnIndex].Name == "Edit")
{
string y = "";
int i;
i = ((DataGridView)sender).SelectedCells[0].RowIndex;
y = ((DataGridView)sender).Rows[i].Cells[1].Value.ToString();
//MessageBox.Show(y.ToString());
DTO.data = y;
Form2 form = new Form2();
form.Show();
Hide();
}
}
Code Select Button in form2 :
private void Btn_select_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
if(fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
textBox1.Text = fbd.SelectedPath;
}
}
Your form should be look like this.
public class Form2 : Form
{
private DataGridViewRow dataGridViewRow;
public Form2(DataGridViewRow row)
{
dataGridViewRow = row;
}
private void Btn_select_Click(object sender, EventArgs e)
{
FolderBrowserDialog fbd = new FolderBrowserDialog();
if (fbd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
textBox1.Text = fbd.SelectedPath;
}
}
private void Btn_Save_Click(object sender, EventArgs e)
{
this.dataGridViewRow.Cells[1].Value = textBox1.Text;
}
}
it main form
private void DGV_sourcefolder_CellClick(object sender, DataGridViewCellEventArgs e)
{
if (DGV_sourcefolder.Columns[e.ColumnIndex].Name == "Edit")
{
string y = "";
int i;
i = ((DataGridView)sender).SelectedCells[0].RowIndex;
y = ((DataGridView)sender).Rows[i].Cells[1].Value.ToString();
//MessageBox.Show(y.ToString());
DTO.data = y;
var row = ((DataGridView)sender).Rows[i];
Form2 form = new Form2(row);
form.Show();
Hide();
}
}
Not assuming anything about the data in your data grid, you can make use of the DataGridViewCell's ParseFormattedValue method and FormatedValue property to make the text box in form2 behave just as a text box in the data grid would. This will help if you are not using string as the value type in your data grid.
public Form2
{
TextBox _myTextBox;
public Form2()
{ ... }
public DataGridViewCell CurrentCell {get;set;}
protected override void OnLoad()
{
Assert(CurrentCell != null);
_myTextBox = CurrentCell.FormatedValue;
}
public SubmitBtn_clicked(...)
{
try
{
var cellValue = CurrentCell.ParseFormattedValue(_myTextBox.Text,
CurrentCell.Style, (TypeConverter)null, (TypeConverter)null);
CurrentCell.Value = cellValue;
}
catch(FormatException)
{/*user entered value that cant be parsed*/ }
catch(ArgumentException)
{/*_myTextBox.Text was null or cell's FormattedValueType is not string*/}
}
}
Here are all my classes.
MainForm = listview,
CustomerFrame = textboxes
When I compile my program, my MainForm appears with an empty listview, and when I press on the add button to insert an item, my CustomerFrame class appears. When writing in the textboxes and clicking ok, no item inserted in my listview (MainForm). Why?
Some code:
MainForm
using(var customerframe = new CustomerFrame())
{
if (customerframe.DialogResult == DialogResult.OK)
{
CustomerFiles.Contact contact = customerframe.GetContact();
CustomerFiles.Address address = customerframe.GetAddress();
CustomerFiles.Phone phone = customerframe.GetPhone();
CustomerFiles.Email email = customerframe.GetEmail();
//Items in my listview
listviewitem = new ListViewItem();
listviewitem.SubItems.Add(contact.FirstName);
listviewitem.SubItems.Add(contact.LastName);
listviewitem.SubItems.Add(phone.Home);
listviewitem.SubItems.Add(phone.Mobile);
listviewitem.SubItems.Add(address.Country);
listviewitem.SubItems.Add(address.ZipCode);
listviewitem.SubItems.Add(address.City);
listviewitem.SubItems.Add(address.Street);
listviewitem.SubItems.Add(email.Personal);
this.listView1.Items.Add(listviewitem);
}
}
MainForm
private void addToolStripMenuItem_Click_1(object sender, EventArgs e)
{
customerframe.Show();
CustomerManager cm = new CustomerManager();
}
CustomerFrame
private void btnOk_Click(object sender, EventArgs e)
{
MainForm main = new MainForm();
DialogResult = DialogResult.OK;
}
By the way, when I use
if (customerframe.ShowDialog() == DialogResult.OK)
this will make the CustomerFrame form appear before the MainForm (which I don't want) and it will insert item, but only once.
Why do you open ANOTHER main form from DialogBox? I think that you should remove this line.
MainForm main = new MainForm();
And add this
DialogResult = DialogResult.OK;
Close();
Argh, to simplify - code in ButtonOK should look like this:
private void btnOk_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.OK;
Close();
}
EDIT: response to new problem
First create new CustomerFrame, show it and wait for it to close; then transfer new data to your ListView. I believe that your add handler should look like this:
private void addToolStripMenuItem_Click_1(object sender, EventArgs e)
{
using(var customerframe = new CustomerFrame())
{
// I don't know what this line does
CustomerManager cm = new CustomerManager();
if (customerFrame.ShowDialog() == DialogResult.OK)
{
CustomerFiles.Contact contact = customerframe.GetContact();
CustomerFiles.Address address = customerframe.GetAddress();
CustomerFiles.Phone phone = customerframe.GetPhone();
CustomerFiles.Email email = customerframe.GetEmail();
//Items in my listview
listviewitem = new ListViewItem();
listviewitem.SubItems.Add(contact.FirstName);
listviewitem.SubItems.Add(contact.LastName);
listviewitem.SubItems.Add(phone.Home);
listviewitem.SubItems.Add(phone.Mobile);
listviewitem.SubItems.Add(address.Country);
listviewitem.SubItems.Add(address.ZipCode);
listviewitem.SubItems.Add(address.City);
listviewitem.SubItems.Add(address.Street);
listviewitem.SubItems.Add(email.Personal);
this.listView1.Items.Add(listviewitem);
}
}
}