Add multiple datagridview to form - c#

I am developing a software and i need different form of a DataGridView.
I created them and inserted them into an array with this method:
private DataGridView[] cloneDataGridViews(int posCount, DataGridView dataGridView)
{
List<DataGridView> dataGridViewList = new List<DataGridView>();
for(int i=0;i<posCount;i++)
{
DataGridView dgv = new DataGridView();
dgv = dataGridView;
dataGridViewList.Add(dgv);
}
return dataGridViewList.ToArray();
}
And I am trying to show them with this code:
void GridViewSelectorLoad(object sender, System.EventArgs e)
{
this.AutoScroll = true;
int startY = 30;
for(int i=0;i<dataGridViewArray.Length;i++)
{
int height = dataGridViewArray[i].Height;
int posY = startY + 10 + i*height;
Panel pnl = new Panel();
pnl.Controls.Add(dataGridViewArray[i]);
dataGridViewArray[i].Parent = pnl;
pnl.Location = new Point(100,posY);
pnl.Name = "pnl"+i.ToString();
pnl.Height = dataGridViewArray[i].Height;
pnl.Width = dataGridViewArray[i].Width;
pnl.Parent = this;
this.Controls.Add(pnl);
}
}
But it shows just one datagridview, how can I show all of them?
What is wrong with that code?

A control can only have one parent, but you're trying to set the same DataGridView as a child of multiple Panels.
for(int i=0;i<posCount;i++)
{
DataGridView dgv = new DataGridView();
dgv = dataGridView; // not creating a new instance of DataGridView
dataGridViewList.Add(dgv);
}
Here's the relevant part of the Controls.Add() method that causes this behavior.
if (value.parent != null)
{
value.parent.Controls.Remove(value);
}
You've got a single instance of DataGridView that you add to each new Panel. Each time, it's Parent property is set to the latest Panel. Then when you try adding it to the next Panel, the code above removes it from the previous one.
If you create a new instance inside the loop, it works fine. You'll need to copy over those values from the existing DataGridView that you wish to have in each new DataGridView instance.
for(int i=0; i<posCount; i++)
{
DataGridView dgv
= new DataGridView
{
Name = dataGridView.Name,
DataSource = dataGridView.DataSource,
...
};
dataGridViewList.Add(dgv);
}

cloneDataGridViews is not cloning the datagrid, its adding the same instance multiple times:
dgv = dataGridView;

It has been pointed out that all you are copying in your code is the same old reference to the same DGV into each slot of your list. Instead you will have to copy both the column structure and the values of all cells like this:
public DataGridView cloneDataGridView(DataGridView oldDGV)
{
DataGridView newDGV = new DataGridView();
foreach (DataGridViewCell cell in oldDGV.Rows[0].Cells)
newDGV.Columns.Add(new DataGridViewColumn(cell));
newDGV.Rows.Add(oldDGV.Rows.Count);
for (int row = 0; row < oldDGV.Rows.Count; row++)
for (int col = 0; col < oldDGV.Columns.Count; col++)
newDGV[col, row].Value = oldDGV[col, row].Value;
return newDGV;
}
You could call it like this:
for(int i=0;i<posCount;i++)
{
DataGridView dgv = cloneDataGridView(dataGridView);
dataGridViewList.Add(dgv);
}
Note: This piece of code assumes that there is at least one row in the source DGV.

Related

Updating dataGridView value from another form

hello experts help please, i have two form in my project and one of those form1 have dataGridView and i want to update the gridview according to text value from form 2,
i had done updating dgv but all row updated on button click event
ex. i have 4 rows different description and cell value after click event
all those 4 rows updating to 1 value.
Form 1
dgv cellmouseclick event
if (e.RowIndex >= 0)
{
DataGridViewRow row = dataGridView2.Rows[e.RowIndex];
_choosenPart = row.Cells[0].Value.ToString();
_choosenQty = row.Cells[2].Value.ToString();
_choosenPrice = row.Cells[4].Value.ToString();
_choosenAmount = row.Cells[5].Value.ToString();
_choosenTotal = row.Cells[7].Value.ToString();
}
FrM_Edit EditGV = new FrM_Edit(this);
EditGV.Show();
In form 2
//constructor
Form F2_main = null;
public FrM_Edit(Form DgVForm1)
{
F2_main=DgVForm1;
InitializeComponent();
}
button click event
r2main_choosenPart = textBox1.Text;
r2main_choosenQty = textBox2.Text;
r2main_choosenPrice = textBox3.Text;
r2main_choosenAmount = textBox4.Text;
r2main_choosenTotal = textBox5.Text;
DataGridView Main_dg = (DataGridView)F2_main.Controls["dataGridView2"];
for (int i = 0; i < Main_dg.Rows.Count; i++)
{
Main_dg.Rows[i].Cells[0].Value = r2main_choosenPart;
Main_dg.Rows[i].Cells[2].Value = r2main_choosenQty;
Main_dg.Rows[i].Cells[4].Value = r2main_choosenPrice;
Main_dg.Rows[i].Cells[5].Value = r2main_choosenAmount;
Main_dg.Rows[i].Cells[7].Value = r2main_choosenTotal;
}
this.Close();
//this for loop takes all rows of your DataGridView. And it is normal that you see that all rows are changing because for all rows, you apply the same code.
DataGridView Main_dg = (DataGridView)F2_main.Controls["dataGridView2"];
for (int i = 0; i < Main_dg.Rows.Count; i++)
{
Main_dg.Rows[i].Cells[0].Value = r2main_choosenPart;
Main_dg.Rows[i].Cells[2].Value = r2main_choosenQty;
Main_dg.Rows[i].Cells[4].Value = r2main_choosenPrice;
Main_dg.Rows[i].Cells[5].Value = r2main_choosenAmount;
Main_dg.Rows[i].Cells[7].Value = r2main_choosenTotal;
}
Instead, you should update only the row that you want to updaate.
You can use differents methods.
For exemple:
for (int i = 0; i < Main_dg.Rows.Count; i++)
{
if( Main_dg.Rows[i].Cells[0].Value == "valueToChange") //Checking an ID or other value.
{
Main_dg.Rows[i].Cells[0].Value = r2main_choosenPart;
Main_dg.Rows[i].Cells[2].Value = r2main_choosenQty;
Main_dg.Rows[i].Cells[4].Value = r2main_choosenPrice;
Main_dg.Rows[i].Cells[5].Value = r2main_choosenAmount;
Main_dg.Rows[i].Cells[7].Value = r2main_choosenTotal;
break; // To break after finding the row that you are looking for.
}
}
Or
for (int i = 0; i < Main_dg.Rows.Count; i++)
{
if(i == 2) //to update the third row of the grid.
{
Main_dg.Rows[i].Cells[0].Value = r2main_choosenPart;
Main_dg.Rows[i].Cells[2].Value = r2main_choosenQty;
Main_dg.Rows[i].Cells[4].Value = r2main_choosenPrice;
Main_dg.Rows[i].Cells[5].Value = r2main_choosenAmount;
Main_dg.Rows[i].Cells[7].Value = r2main_choosenTotal;
break; // To break after finding the row that you are looking for.
}
}
Or you can use your DataGridViews selected row to update.

How to add multiple TextBox follow by DataGridView.Columns.Count and column data.TQ

//...
{
public Form1()
{
InitializeComponent();
LoadData();
textBoxFill();
}
private void LoadData()
{
SqlConnection SCConnect = new SqlConnection("Server=localhost;Initial Catalog=T8;Integrated Security=SSPI;");
SCConnect.Open();
StringBuilder SBBuilder = new StringBuilder("Select * from Table8");
SqlDataAdapter SDA = new SqlDataAdapter(SBBuilder.ToString(), SCConnect);
SqlCommandBuilder SCB = new SqlCommandBuilder(SDA);
DataTable DT = new DataTable();
SDA.Fill(DT);
dataGridView1.DataSource = DT;
}
private void textBoxFill()
{
TextBox TB = new TextBox();
int A = 1;
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
panel1.Controls.Add(TB);
TB.Location = new Point(10, (A * 20));
TB.Top = A * 28;
TB.Size = new Size(200, 50);
TB.Margin = new Padding(10, 10, 10, 10);
}
A = A + 1;
}
}
How do I add multiple TextBox follow by DataGridView.Columns.Count and
each TextBox to fill in each DataGridView columns data.TQ?
I am guessing after looking at the previous duplicate post, that this may be what you are looking for. It may help you if you explained the overall picture as this seems like on odd thing to do since the data is already in the grid and the user can edit it, I am not sure why you would do this data “duplication” in the panel.
However, it does appear you want to have the textboxes correspond to the currently “selected” row in the grid. Such that there will be one textbox for each column in the grid. Initially, you do know how many columns the data may contain. Therefore, you need to dynamically create the textbox’s in the panel.
One approach to “bind” each textbox to a column of the currently selected row in the grid may be accomplished by “binding” each textbox to a particular column in the DataTable that is used as the DataSource to the grid. Each textbox has a property called…DataBindings. This property will allow you to “bind” the textbox to a particular column in the DataTable. Below is an example.
To help, given we have the data, I suggest a method AddTextBoxesToPanel(DataTable dt) … that takes a DataTable and loops through the columns of that table and creates a textbox for each column AND adds the “binding” for that column to that textbox. With this approach, no extra code will be necessary to fill the text boxes when the user selects different rows.
private void AddTextBoxesToPanel(DataTable dt) {
panel1.Controls.Clear();
panel1.AutoScroll = true;
panel1.AutoScrollMinSize = new Size(0, (dt.Columns.Count * 23) + 15);
TextBox curTB;
int y = 10;
foreach (DataColumn col in dt.Columns) {
curTB = GetTextBox(10, y);
curTB.DataBindings.Add(new Binding("Text", dt, col.ColumnName));
panel1.Controls.Add(curTB);
y += 23;
}
}
Above, we assume this may be called more than once and need to “clear” any previous textboxs in the panel. Set the panel to be scrollable, then start the loop through the columns to add the textboxes to the panel. The GetTextBox method (below) simply gets a new TextBox with the desired location. Lastly, we set the DataBinding for “that” textbox to point to “that” column. curTB.DataBindings.Add(new Binding("Text", dt, col.ColumnName));
private TextBox GetTextBox(int xLoc, int yLoc) {
TextBox TB = new TextBox {
Text = "",
Location = new Point(xLoc, yLoc),
Size = new Size(150, 50),
Margin = new Padding(10),
Anchor = AnchorStyles.Left
};
return TB;
}
Below is a complete example using the above method. The Forms Load method to fill a DataTable with 10 columns and 20 rows, then use that DataTable as a DataSource to the grid. Then call the method above to set the textboxes into the panel.
private void Form1_Load(object sender, EventArgs e) {
FillGrid(10, 20);
AddTextBoxesToPanel((DataTable)dataGridView1.DataSource);
}
A method to generate some data for testing.
private void FillGrid(int totalColumns, int totRows) {
DataTable dt = new DataTable();
// add columns
for (int i = 0; i < totalColumns; i++) {
dt.Columns.Add("Col" + i, typeof(string));
}
// add rows
object[] data = new object[totalColumns];
for (int row = 0; row < totRows; row++) {
for (int col = 0; col < totalColumns; col++) {
data[col] = "Col" + col + "Row" + row;
}
dt.Rows.Add(data);
}
dataGridView1.DataSource = dt;
}
Hope this helps.

How to display data from an array in a grid in WindowsForms - C#

I have a WindowsForms application that I am compiling as a DLL to be used by another program. This program supplies the DLL with an array filled with information(floats). What I want to do is display these numbers in an organized way(row and columns). The methods I've investigated so far incorporate the use of a DataGridView object, however I do not have a "database", I only have the raw data stored as an array.
Would the only way to do this involve creating a SQL database with my data from the array? Or is there an easier/faster way of doing this?
Thanks for the replies, but I just ended up looping through the creation of the rows and columns and filling them with my required data.
Creating/initializing DataGridView:
private System.Windows.Forms.DataGridView dataGridView1;
this.dataGridView1 = new System.Windows.Forms.DataGridView();
//Size and location can be changed to whatever you want
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Location = new System.Drawing.Point(12, 436);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.RowHeadersWidth = 70; //Adjusts row header to fit entire "Score" string
this.dataGridView1.Size = new System.Drawing.Size(976, 398);
this.dataGridView1.TabIndex = 10;
Creating rows/columns and filling them with my data:
for (int i = 0; i <= 40; i++)
{
dataGridView1.Columns.Add("column" + i.ToString(), i.ToString());
dataGridView1.Columns[i].Width = 22;
}
DataGridViewRow row = (DataGridViewRow)dataGridView1.Rows[0].Clone();
for (int i = 0; i <= 40; i++)
{
row.Cells[i].Value = scores[0,i]; // "scores" is an Int32[,] array filled with my data
}
dataGridView1.Rows.Add(row);
dataGridView1.Rows[0].HeaderCell.Value = "Score";
The result looked something like this.
You can send the gridview data in XML format
private void Form1_Load(object sender, EventArgs e) {
DataSet ds = new DataSet();
ds.ReadXml(#"XMLFile1.xml");
gridControl1.DataSource = ds.Tables[1];
gridView1.PopulateColumns();
}

Looping through WPF Grid

I have a dynamically created WPF Grid (rows and columns count based on layout) like this:
private Grid CreateGrid(string layout)
{
int col;
int row;
if (layout == "4x4")
{
row = 4;
col = 4;
}
else
{
row = 2;
col = 2;
}
Grid output = new Grid();
for (int i = 0; i < col; i++)
{
ColumnDefinition coldef = new ColumnDefinition();
coldef.Width = GridLength.Auto;
output.ColumnDefinitions.Add(coldef);
}
for (int i = 0; i < row; i++)
{
RowDefinition rowdef = new RowDefinition();
rowdef.Height = GridLength.Auto;
output.RowDefinitions.Add(rowdef);
}
return output;
}
In each of these "cells" should be another object, filled with data from dataSet (one table per object). That object is also another set of grids. My aim is to loop through this dynamically created grid and put this object into each cell. (and if there is layout 2x2 but only 3 tables in the dataset, I want only 3 object there and last cell would be empty)
However, I did not find anything like "foreach column in grid", or even how to get column / row count. On the other hand, all I found was related to DataGrid or GridView - what is the difference, and if the other type would be better to use for this, why?
Thanks in advance
So, I was able to find a solution to this. It might not be the best one, but it works.
Here is the code:
foreach (DataTable table in result.Tables)
{
GfoTopBox box1 = StuffData(table);
Grid.SetRow(box1, j);
Grid.SetColumn(box1, i);
output.Children.Add(box1);
i++;
if (i >= output.ColumnDefinitions.Count)
{
i = 0;
j++;
}
}
"result" is the data set, each table provides the data for one of the objects I wanted to put in the cells of the Grid in the question (output).
However, if anyone has better solution, I am open to suggestions :)

Deleting Grid View Row data wrongly Windows Form My Code Attached?

i am trying to delete grid view data as i am filling grid like,
public void FillCompanyInfo()
{
DataTable dtCompanyInfo = new DataTable();
dtCompanyInfo = objFunctions.GetCompanyInfo();
if(dtCompanyInfo.Rows.Count>0)
{
dgvCompany.DataSource = dtCompanyInfo;
}
if (dtCompanyInfo.Rows.Count > 0)
{
if (this.dgvCompany.Columns.Count == 8)
{
DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "";
checkColumn.HeaderText = "Select";
checkColumn.Width = 50;
checkColumn.ReadOnly = false;
checkColumn.FillWeight = 10; //if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values\\
dgvCompany.Columns.Add(checkColumn);
}
}
}
After filling grid i click on grid row and click delete button as,
private void btn_Delete_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow r in dgvCompany.Rows)
{
if (Convert.ToBoolean(r.Cells[8].Value)) //cells[4] CONTAINS CHECKBOX COLUMN
{
string strId = r.Cells[1].Value.ToString(); //cells[0] CONTAINS EMPIDCOLUMN
objFunctions.DeleteCompany(strId);
}
}
FillCompanyInfo();
}
But it delete the data wrongly in my grid view i get fields numeric and string from 0 to 6 and chk box at 7th place while after binding data to grid i also attach one more column at 8 place may me it is due to some that reason ?
while debugging i suddenly notice at this place,
foreach (DataGridViewRow r in dgvCompany.Rows)
that grid view have column in this manner chk box at zero position then seven fild and again then chk box at 8 place how it change the order ?
hopes for your suggestion thanks in advance
You need to clear the grid view data source before bind it.Please Refer this link to clear grid view. try this code
Datagridview remove all columns
public void FillCompanyInfo()
{
dataGridView1.DataSource = null;
dataGridView1.Columns.Clear();
dtCompanyInfo = GetCompanyInfo();
if (dtCompanyInfo.Rows.Count > 0)
{
dataGridView1.DataSource = dtCompanyInfo;
DataGridViewCheckBoxColumn checkColumn = new DataGridViewCheckBoxColumn();
checkColumn.Name = "";
checkColumn.HeaderText = "Select";
checkColumn.Width = 50;
checkColumn.ReadOnly = false;
checkColumn.FillWeight = 10; //if the datagridview is resized (on form resize) the checkbox won't take up too much; value is relative to the other columns' fill values\\
dataGridView1.Columns.Add(checkColumn);
}
}

Categories

Resources