I am having issues transfering data points from one form to another. I have made sure that the button inside of addTagsForm has a public modifier.
I've looked at multiple solutions of using data values from one form to another and I must be missing something from them.
Here is what I have in Form1:
//Inside Form1
XMLDocGen.PLCData PLC = new XMLDocGen.PLCData();
List<XMLDocGen.TagData> tags = new List<XMLDocGen.TagData>();
AddTagsForm addTagsForm = new AddTagsForm();
addMoreTagsSelected = addTagsForm.addMoreTagsEnabled;
if(addMoreTagsSelected)
{
for(int i= 0; i < 8; i++)
tags.Add(new XMLDocGen.TagData(addTagsForm.addTags[i], addTagsForm.addDataTypes[i], addTagsForm.addElemSizes[i], addTagsForm.addElemCounts[i]));
}
Here is what is inside of addTagsForm
public void button1_Click(object sender, EventArgs e)
{
addMoreTagsEnabled = true;
var tagNames = new List<TextBox>() { tagNameBoxAMT1, tagNameBoxAMT2, tagNameBoxAMT3, tagNameBoxAMT4, tagNameBoxAMT5, tagNameBoxAMT6, tagNameBoxAMT7, tagNameBoxAMT8 };
var dataTypes = new List<ComboBox>() { dataTypeBoxAMT1, dataTypeBoxAMT2, dataTypeBoxAMT3, dataTypeBoxAMT4, dataTypeBoxAMT5, dataTypeBoxAMT6, dataTypeBoxAMT7, dataTypeBoxAMT1 };
var elemSizes = new List<TextBox>() { elemSizeBoxAMT1, elemSizeBoxAMT2, elemSizeBoxAMT3, elemSizeBoxAMT4, elemSizeBoxAMT5, elemSizeBoxAMT6, elemSizeBoxAMT7, elemSizeBoxAMT8 };
var elemCounts = new List<TextBox>() { elemCountBoxAMT1, elemCountBoxAMT2, elemCountBoxAMT3, elemCountBoxAMT4, elemCountBoxAMT5, elemCountBoxAMT6, elemCountBoxAMT7, elemCountBoxAMT8 };
for (int i = 0; i < 8; i++)
{
addTags.Add(tagNames[i].Text);
addDataTypes.Add(dataTypes[i].Text);
addElemSizes.Add(elemSizes[i].Text);
addElemCounts.Add(elemCounts[i].Text);
}
this.Hide();
}
I have checked to make sure each list is populated correctly and they are. As well as the Lists being public. The problem is trying to grab these values from Form1. There has to be something simple that I'm missing! Thanks for the help!
With the reference of your comment i've generated an idea for you. By writing a simple public Action in your Second form Form2 you can achieve your goal. Below i'm showing an example:
Declare a public Action in your Form2 global scope with your desired collection type, like this way:
public Action<List<TextBox>, List<ComboBox>> actGetCollection;
Keep a method with some of your desired collection type parameter in your Form1 like this way:
private void GetCollectionItems(List<TextBox> addTags, List<ComboBox> addDataTypes)
{
//you will get your list items here and do whatever you want with these
}
In your Form1 from where your second form will open bind your GetCollectionItems() method with your Action in Form2 (assuming you do this in a button's click event) like this way:
private void button1_Click(object sender, EventArgs e)
{
//create an instance of your Form2 Form
Form2 obj = new Form2();
//bind your function with the action
obj.actGetCollection = GetCollectionItems;
//then call your Form2's ShowDialog() method to show the form
obj.ShowDialog();
//now your Form2 is opended
}
Now in your Form2's button_click event do this:
public void button1_Click(object sender, EventArgs e)
{
addMoreTagsEnabled = true;
var tagNames = new List<TextBox>() { tagNameBoxAMT1, tagNameBoxAMT2, tagNameBoxAMT3, tagNameBoxAMT4, tagNameBoxAMT5, tagNameBoxAMT6, tagNameBoxAMT7, tagNameBoxAMT8 };
var dataTypes = new List<ComboBox>() { dataTypeBoxAMT1, dataTypeBoxAMT2, dataTypeBoxAMT3, dataTypeBoxAMT4, dataTypeBoxAMT5, dataTypeBoxAMT6, dataTypeBoxAMT7, dataTypeBoxAMT1 };
var elemSizes = new List<TextBox>() { elemSizeBoxAMT1, elemSizeBoxAMT2, elemSizeBoxAMT3, elemSizeBoxAMT4, elemSizeBoxAMT5, elemSizeBoxAMT6, elemSizeBoxAMT7, elemSizeBoxAMT8 };
var elemCounts = new List<TextBox>() { elemCountBoxAMT1, elemCountBoxAMT2, elemCountBoxAMT3, elemCountBoxAMT4, elemCountBoxAMT5, elemCountBoxAMT6, elemCountBoxAMT7, elemCountBoxAMT8 };
for (int i = 0; i < 8; i++)
{
addTags.Add(tagNames[i].Text);
addDataTypes.Add(dataTypes[i].Text);
addElemSizes.Add(elemSizes[i].Text);
addElemCounts.Add(elemCounts[i].Text);
}
//call the action
if(actGetCollection != null)
actGetCollection(addTags, addDataTypes);
this.Hide();
}
When your Form2 wil disappear your code will get back to your Form1's event from where you're called your Form2. Now in your GetCollectionItems() you've the collection items that you're wanted.
You can set stuff in your second form from your first:
class Form1
{
...
public void OnButtonPress()
{
var anotherForm = new Form2();
anotherForm.AList = mylist;
anotherForm.BList = myBList;
anotherForm.ShowDialog();
}
}
Alternatively, you could create a class that encapsulates everything you want to pass between the two and so only pass on thing. If it's mandatory I would put it in Form2's constructor:
public Form2(MyImportantStuff stuff)
Related
I have a dataGridView in form1 where I can add rows programatically and I want to get all its values and transfer it to form 2 where I can insert it inot a database one by one
Here's a minimal, but working example.
You can pass any type, to any method... for as long as the method is expecting the type as incoming parameter.
private void DoSomething(string withThisString)
In that method declaration, I declared that ...
the method is private aka accessible to this class only
the method returns void aka does not return anything
the method name is DoSomething
the method is expecting a string parameter
You want to do something similar in your case. But you... you don't want to be passing string as parameter, you want to pass DataGridViewRow... Actually no... you want to pass multiple rows so lets aggregate the rows in a List<DataGridViewRow> and we'll pass a list of rows, instead of passing a single row.
List<DataGridViewRow> listofrows = new List<DataGridViewRow>();//we'll agregate our desired rows in this
//itterate through the rows of the DataGridView
foreach (DataGridViewRow item in dgv1.Rows)
{
DataGridViewRow r = (DataGridViewRow)item.Clone();//clone the desired row
//Oddly enough... cloning does not clone the values... So lets put the values back in their cells
for (int i = 0; i < item.Cells.Count; i++)
{
r.Cells[i].Value = item.Cells[i].Value;
}
listofrows.Add(r);//add the row to the list
}
Also, you don't want to be passing that parameter to DoSomething, you want to pass it to the method that is responsible of "initializing" the Form2.
By default, when you create a new form... the form constructor is written like this
public Form2()
{
InitializeComponent();
}
public Form2() as we can see in the (), this method is not expecting any parameters to work. Actually, even if you wanted to, you couldn't pass it anything because that method is not ready for anything. It just works alone...
But you want to pass around some DataGridViewRow, so lets modify the method declaration a bit
public Form2(List<DataGridViewRow> dgvc = null)
{
InitializeComponent();
}
public Form2(List<DataGridViewRow> dgvc = null) as we can see in the (), this method is now expecting to receive a List<DataGridViewRow> to work.
Now that Form2 is expecting the parameter I have for it... We can use it once we are done making our list of rows!
//Make an instance of Form2, passing it the list of Rows we just created
Form2 f2 = new Form2(listofrows);
f2.Show();//show the form
Having said all that. To accomplish your goal, at a high level, you want to
iterate through the rows of your DataGridView
accumulate the desired rows in a List or whatever you pick
pass the List as parameter to Form2
have Form2 perform whatever task you want with the incoming List of DataGridViewRow
Form1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace DataGridViewRowsToForm2_46306622
{
public partial class Form1 : Form
{
DataGridView dgv1 = new DataGridView();
BindingList<dgventry> dgv1Data = new BindingList<dgventry>();
Button btn = new Button();
public Form1()
{
InitializeComponent();
InitializeGrid();
AddButton();
AddData();
}
private void AddButton()
{
btn.Location = new Point(5, dgv1.Location.Y + dgv1.Height + 5);
btn.Text = "Click to pass rows";
btn.Click += Btn_Click;
this.Controls.Add(btn);
}
private void Btn_Click(object sender, EventArgs e)
{
List<DataGridViewRow> listofrows = new List<DataGridViewRow>();
foreach (DataGridViewRow item in dgv1.Rows)
{
DataGridViewRow r = (DataGridViewRow)item.Clone();
for (int i = 0; i < item.Cells.Count; i++)
{
r.Cells[i].Value = item.Cells[i].Value;
}
listofrows.Add(r);
}
Form2 f2 = new Form2(listofrows);
f2.Show();
}
private void AddData()
{
for (int i = 0; i < 5; i++)
{
dgv1Data.Add(new dgventry
{
col1 = "row " + i,
col2 = i.ToString(),
col3 = i.ToString()
});
}
}
private void InitializeGrid()
{
dgv1.Location = new Point(5, 5);
dgv1.DataSource = dgv1Data;
this.Controls.Add(dgv1);
}
}
public class dgventry
{
public string col1 { get; set; }
public string col2 { get; set; }
public string col3 { get; set; }
}
}
Form2.cs
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
namespace DataGridViewRowsToForm2_46306622
{
public partial class Form2 : Form
{
//Have a form constructor that accepts your GridViewRows as argument
public Form2(List<DataGridViewRow> dgvc = null)
{
InitializeComponent();
TextBox txtbx = new TextBox();
txtbx.Location = new Point(5, 5);
if (dgvc != null)
{
//iterate through the rows and do what you want with them
foreach (DataGridViewRow item in dgvc)
{
txtbx.Text += item.Cells[0].Value + " / ";
}
}
this.Controls.Add(txtbx);
}
}
}
Some people will suggest passing the DataSource instead. Sure, that will work... for as long as your DataSource matches the content of the DataGridView; It's not necessarily the case all the time so pick your poison accordingly.
I have a main form which is called form and a second form called form2. Form contains a button with a coded function inside. Now on my form2 I have the same button which performs the same function on form or which I want it to perform the same function as form1.
On form2 I have created a button of which I want it to use the same function from the form1. Now I want to be able to click the button from form2 and it calls the button funtion from form1.
I have done this but I don't know how I can make it work
Form1 (mainform)
public Button newButton
{
get
{
return btnNewfile;
}
}
public void SetLanguage(string cbolang)
{
cboLanguage.SelectedValue = cbolang;
}
Form2
public frmMain_Page _frmMainform;
public FrmLanguage(frmMain_Page _frmMainform)
{
InitializeComponent();
this._frmMainform = _frmMainform;
}
public frmMain_Page _Main
{
get;
set;
}
//from this button I can't get the main button from the main form
private void btnCreatFile_Click(object sender, EventArgs e)
{
_frmMainform.newButton.btnNewfile;
//Error 19 'System.Windows.Forms.Button' does not contain a definition for 'btnNewfile' and no extension method 'btnNewfile' accepting a first argument of type 'System.Windows.Forms.Button' could be found (are you missing a using directive or an assembly reference?)
}
this is the button with coded function. am trying to take it from this button
private void btnNewfile_Click(object sender, EventArgs e)
{
_frmMainform.newButton;
XmlDocument _doc = new XmlDocument();
FileInfo _fileInfo = new FileInfo(txtInputfile.Text);
_InputFileName = _fileInfo.Name;
_InputFileSourceDirectory = _fileInfo.DirectoryName;
_InputFileExternsion = _fileInfo.Extension;
_OutFileName = cboLanguage.SelectedItem.ToString() + "-language.resx";
string outputFilePath = txtInputfile.Text.Replace(_InputFileName, _OutFileName);
File.Copy(txtInputfile.Text, outputFilePath);
string text = File.ReadAllText(outputFilePath);
XDocument doc = XDocument.Load(outputFilePath);
foreach (var valueNode in doc.Descendants("data").SelectMany(n => n.Elements("value")))
{
valueNode.Value = string.Empty;
}
foreach (var commentNode in doc.Descendants("data").SelectMany(n => n.Elements("comment")))
{
commentNode.Value = DeleteBetween(commentNode.Value, "Font");
commentNode.Value = DeleteBetween(commentNode.Value, "DateStamp");
commentNode.Value = DeleteBetween(commentNode.Value, "Comment");
}
doc.Save(outputFilePath);
txtOutputfile.Text = _InputFileSourceDirectory + "\\" + _OutFileName;
_doc.Load(outputFilePath);
string xmlcontents = _doc.InnerXml;
//lblversion.Text = updateversion.ToString();
}
private void btnCreatFile_Click(object sender, EventArgs e)
{
// because newButton returns btnNewfile
// You can access btnNewLife by : _frmMainform.newButton
_frmMainform.newButton.Text = "My Button";
}
Also your newButton returns a Button object.
A Button object dose not have a child Button.
So you just need to access newButton to get btnNewLife.
how to tranfer Form1 checked GridView Rows Data on Form2 Gridview?
Like This:
There are lot of ways to achieve this. The simplest that comes in my mind is:
-Create an istance of GetDataForm and call a method which displays the form and get the result:
GetDataForm form2 = new GetDataForm();
List<DataGridViewRow> res = form2.ShowForm();
for (int i = 0; i < res.Count; i++)
mainFormGrid.Rows.Add(res[i]);
-In your GetDataForm you should have the following method:
bool _closedByTransferButton = false;
public List<DataGridViewRow> ShowForm()
{
ShowDialog();
List<DataGridViewRow> res = new List<DataGridViewRow>();
if(_closedByTransferButton)
{
for(int i = 0;i<grid.Rows.Count;i++)
if((bool)grid.Rows[i].Cells["checkboxColumn"].Value)
res.Add(grid.Rows[i]);
}
return res;
}
-And the Click event of your Transfer button should be:
private void tranferButton_Click(object sender, EventArgs e)
{
_closedByTransferButton = true;
Close();
}
Hope this helps.
I have two forms (Form 1 and Form 2), I am successful in passing a data table from Form 1 to Form 2 by filling a data grid view in a dialog box. I also have an event handler to capture double click events on a selected row. When the event occurs I want to set textboxes in form 1 from the click event in form 2. No matter what I try I can not seem to show the text inside the textboxes. Below is my code:
//Code begins here
//....Function to fill data table from form 1 and pass to form 2
private void buttonNewEntryLookUp_Click(object sender, EventArgs e)
{
try
{
cs.Open();
da.SelectCommand = new SqlCommand("Select ctx_customername AS Customer, ctx_contactname AS Contact, ctx_custaddress1 AS Address, ctx_custcity AS City, ctx_custstate AS State, nno_custzip AS ZIP, ctx_custemail AS Email FROM Customers WHERE nno_custphone = '" + maskedTextBoxNewLogTel.Text + "'", cs);
dt.Clear();
da.Fill(dt);
}
catch
{
MessageBox.Show("Connection to Database could not be established, please close this application and try again. If problem continues please contact server Admin. Thank you.", "AAMP");
//Display this message if connection could not be made
}
cs.Close();//close connection to db
if (dt.Rows.Count == 0)//if there are no returned results then this must be a new entry into the database
{
MessageBox.Show("Phone Number Not Found in Database.", "AAMP");
}
else//number was found
{
Form2 form2 = new Form2(dt);//create object of form 2 and pass the data table.
form2.ShowDialog();//show form 2 with data table in the grid view.
}
}
public void getContactInfo(string[] contactInfo)
{
textBoxNewLogCustomerName.Text = contactInfo[0];
textBoxNewLogContactName.Text = contactInfo[1];
textBoxNewLogAddress.Text = contactInfo[2];
textBoxNewLogCity.Text = contactInfo[3];
textBoxNewLogState.Text = contactInfo[4];
textBoxNewLogZIP.Text = contactInfo[5];
textBoxNewLogEmail.Text = contactInfo[6];
}
//code for form 2
public partial class Form2 : Form
{
/*Globals for Form 2*/
DataTable g_dt;
public Form2(DataTable dt)
{
InitializeComponent();
dataGridViewLookUp.DataSource = dt;
g_dt = dt;
}
private void dataGridViewLookUp_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
Form1 form1 = new Form1();
string[] contactInfo = new string[7];
contactInfo[0] = Convert.ToString(g_dt.Rows[e.RowIndex]["Customer"]);
contactInfo[1] = Convert.ToString(g_dt.Rows[e.RowIndex]["Contact"]);
contactInfo[2] = Convert.ToString(g_dt.Rows[e.RowIndex]["Address"]);
contactInfo[3] = Convert.ToString(g_dt.Rows[e.RowIndex]["City"]);
contactInfo[4] = Convert.ToString(g_dt.Rows[e.RowIndex]["State"]);
contactInfo[5] = Convert.ToString(g_dt.Rows[e.RowIndex]["ZIP"]);
contactInfo[6] = Convert.ToString(g_dt.Rows[e.RowIndex]["Email"]);
form1.getContactInfo(contactInfo);//return the row number being clicked.
this.Close();
}
}
I am successful in passing the data table to form 2 and capturing the correct information to fill the string array but when I pass the string array back by calling the getContactInfo function I can not seem to set my textboxes with the data. Can someone please, please help!
Thanks.
Your OP is a little vague, but I have some code that does this, takes some data in form 2 and sends it back to form 1.
Here's the code from form1:
private void btnGroupNameLookup_Click(object sender, EventArgs e)
{
//instantiate an instance of the grp name lookup form
frmGroupNameLookup lookupName = new frmGroupNameLookup();
//add an event handler to update THIS form when the lookup
//form is updated. (This is when LookupUpdated fires
lookupName.GroupNamesFound += new frmGroupNameLookup.LookupHandler(lookupName_GroupNamesFound);
//rc.ReconCFUpdated += new ReconCaseFileChecklist.ReconCFListHandler(ReconCFForm_ButtonClicked);
lookupName.Show();
}
void lookupName_GroupNamesFound(object sender, GroupNameLookupUpdateEventArgs e)
{
//update the list boxes here
foreach (string s in e.Parents)
{
lstFilteredGroupParents.Items.Add(s);
}
foreach (string s in e.Groups)
{
lstFilteredGroups.Items.Add(s);
//link supgroups and plan ids
GetFilteredSubgroupNos(s);
GetFilteredPlanIds(s);
}
//ensure dupes are stripped out
//filter out duplicates
var noDupeSubgroups = subgroupList.Distinct().ToList();
noDupeSubgroups.Sort();
foreach (string s in noDupeSubgroups)
{
lstFilteredSubgroups.Items.Add(s);
}
var noDupePlanIDs = planIDList.Distinct().ToList();
noDupePlanIDs.Sort();
foreach (string s in noDupePlanIDs)
{
lstFilteredPlanID.Items.Add(s);
}
}
From Form2
public partial class frmGroupNameLookup : Form
{
//add a delegate, the GroupNameLookupUpdateEventArgs class is defined at the bottom
//of this file
public delegate void LookupHandler(object sender, GroupNameLookupUpdateEventArgs e);
//add an event of the delegate type
public event LookupHandler GroupNamesFound;
//this event closes the forms and passes 2 lists back to form 1
private void btnCommit_Click(object sender, EventArgs e)
{
List<string> prnt = new List<string>();
List<string> grp = new List<string>();
//get selected rows
if (grdLookup.SelectedRows.Count > 0)
{
foreach (DataGridViewRow row in grdLookup.SelectedRows)
{
prnt.Add(row.Cells[0].Value.ToString());
grp.Add(row.Cells[1].Value.ToString());
}
//filter out duplicates
var noDupeParentGroups = prnt.Distinct().ToList();
noDupeParentGroups.Sort();
// instance the event args and pass it each value
GroupNameLookupUpdateEventArgs args =
new GroupNameLookupUpdateEventArgs(noDupeParentGroups, grp);
// raise the event with the updated arguments
this.GroupNamesFound(this, args);
this.Dispose();
}
}
}
public class GroupNameLookupUpdateEventArgs : System.EventArgs
{
// add local member variables to hold text
private List<string> mParents = new List<string>();
private List<string> mGroups = new List<string>();
// class constructor
public GroupNameLookupUpdateEventArgs(List<string> sParents, List<string> sGroups)
{
this.mParents = sParents;
this.mGroups = sGroups;
}
// Properties - Viewable by each listener
public List<string> Parents
{
get { return mParents; }
}
public List<string> Groups
{
get { return mGroups; }
}
}
Simple. Make the contact information a method public in Form2 and then just assign it after the ShowDialog() in form1.
else//number was found
{
Form2 form2 = new Form2(dt);//create object of form 2 and pass the data table.
form2.ShowDialog();//show form 2 with data table in the grid view.
getContactInfo(form2.ContactInfoFromForm2);
}
You're passing the datatable into the constructor of Form2:
Form2 form2 = new Form2(dt);
You could instead pass a reference to the entire Form1:
Form2 form2 = new Form2(this);
Then you make public methods on Form1 that Form2 can use to update data. Something like this:
//In Form1
public DataTable getDataTable(){
//return datatable
}
public void setTextBoxValue(string Value){
//Set the value
}
And then in Form2
private Form1 _form1;
public Form2(Form1 form1){
_form1 = form1;
dataGridViewLookUp.DataSource = _form1.getDataTable();
g_dt = dt;
}
private void dataGridViewLookUp_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
_form1.setTextBoxValue(Convert.ToString(g_dt.Rows[e.RowIndex]["Customer"]));
//etc
}
Are you getting an error or is the data just not displaying. Maybe try a ToString() method behind each stringarray index in the getcontactinfo method. (i.e. contactInfo[0].ToString();)
I want to hide a button when the DateTime.Now = a input date by user. The textbox100 is in the Form2 and is already public, but I know something else is missing, because I get the error: "The name 'textBox100' does not exist in the current context."
Thank you.
public void Form1_Load(object sender, EventArgs e)
{
var dateTimeStr = textBox100.Text;
var user_time = DateTime.Parse(dateTimeStr);
var time_now = DateTime.Now;
if (time_now >= user_time)
{
button1.Visible = false;
}
}
You need to improve your communication between the forms. See the accepted answer in this question.
Adapted to your code:
using ( var form = new Form2() )
{
var dateTimeStr = form.textBox100.Text;
var user_time = DateTime.Parse(dateTimeStr);
var time_now = DateTime.Now;
if (time_now >= user_time)
{
button1.Visible = false;
}
}
If you need to wait before taking the value of the TextBox, that is, wait for the user to type in the input, then you can write:
string dateTimeStr;
using ( var form = new Form2() )
{
form.submitButton.OnMouseUp += (source, e) =>
{
dateTimeStr = form.textBox100.Text;
};
}
Assuming you have a submission button somewhere in your form.
even if it's public, it still belongs to the class Form2
var dateTimeStr = Form2.textBox100.Text;
You cant get the text of textbox100 if Form2 not instantiated an having a reference in Form1. Then use the line from UnLoCo. Of course its has to be public in Form2