Resize the table to fit the data grid view C# - c#

I want my table size to fit the data grid view. The data grid view size is always the same but the table can change in amount of rows and columns.
Here is how I populate the table:
public DataTable createGridForForm(int rows, int columns)
{
// Create the output table.
DataTable table = new DataTable();
for (int i = 1; i <= columns; i++)
{
table.Columns.Add("column " + i.ToString());
}
for (int i = 1; i < rows; i++)
{
DataRow dr = table.NewRow();
// populate data row with values here
ListBox test = new ListBox();
myTabPage.Controls.Add(test);
table.Rows.Add(dr);
}
return table;
}
And here is how I create the datagridview:
private void createGridInForm(int rows, int columns)
{
DataGridView RunTimeCreatedDataGridView = new DataGridView();
RunTimeCreatedDataGridView.DataSource = createGridForForm(rows, columns);
//DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
//ID_Column.Width = 200;
int positionForTable = getLocationForTable();
RunTimeCreatedDataGridView.BackgroundColor = Color.WhiteSmoke;
RunTimeCreatedDataGridView.Size = new Size(995, 200);
RunTimeCreatedDataGridView.Location = new Point(5, positionForTable);
myTabPage.Controls.Add(RunTimeCreatedDataGridView);
}
I am getting an error when trying this code:
//DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
//ID_Column.Width = 200;
the error says that the:
Index was out of range. It may not be negative and must be smaller than the size

this is it
for the width-
RunTimeCreatedDataGridView.AutoSizeColumnsMode=System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
and for the height --
totalRowHeight = RunTimeCreatedDataGridView.ColumnHeadersHeight;
foreach (DataGridViewRow row in RunTimeCreatedDataGridView.Rows)
totalRowHeight += row.Height;

If you add your datagrid to your tab control before get Columns[0] you don't get that error.
Your code should be like that:
DataGridView RunTimeCreatedDataGridView = new DataGridView();
myTabPage.Controls.Add(RunTimeCreatedDataGridView);
RunTimeCreatedDataGridView.DataSource = createGridForForm(rows, columns);
DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
ID_Column.Width = 200;
EDIT:
I add detailed lines to fill your DataGridView to it's container.
private void createGridInForm(int rows, int columns)
{
DataGridView RunTimeCreatedDataGridView = new DataGridView();
RunTimeCreatedDataGridView.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right)));
myTabPage.Controls.Add(RunTimeCreatedDataGridView);
RunTimeCreatedDataGridView.DataSource = createGridForForm(rows, columns);
// fill the gridview to its container
DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
ID_Column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
RunTimeCreatedDataGridView.Dock = DockStyle.Fill;
}

following line can be used to fill extra space with a specific column in a data grid view
RunTimeCreatedDataGridView .Columns["column_name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
if you set this property of all column to DataGridViewAutoSizeColumnMode.Fill then all column takes same width

Related

Devexpress : set column and row count to integer value

basically want to set the column count and row count equal to 1 using devexpress.
//int startcolumn= 1;
//int startrow = 1;
//GridControl gd = new Gridcontrol();
//somefunction()
//{
//gd.colcount = startcolumn; //colcount & rowcount is a syncfusion type
//gd.rowcount = stratrow;
//}
how to achieve it in devexpress, please help, any similar property like colcount in devexpress or any other way to achieve it?
GridControl is not a matrix-editor. GridControl is a control for showing data. You can't just set number of columns and rows.
You can dynamically add new column:
DataColumn col = jobTable.Columns.Add("columnKey", typeof(string));
GridColumn column = gridViewJob.Columns.AddVisible(col.ColumnName)
column.Caption = col.Caption;
column.Name = col.ColumnName;
and add new row.

Putting a listbox/dropdown menu in a data grid view C#

I have a data table in a data grid view. I want to put an listbox/dropdown menu in a specific column and row. I have tried this but it doesn't work --
var column = new DataGridViewComboBoxColumn();
RunTimeCreatedDataGridView[1, 1].Value = RunTimeCreatedDataGridView.Columns.Add(column);
Here is how I populate the table--
public DataTable createGridForForm(int rows, int columns)
{
// Create the output table.
DataTable table = new DataTable();
for (int i = 1; i <= columns; i++)
{
table.Columns.Add("column " + i.ToString());
}
for (int i = 1; i < rows; i++)
{
DataRow dr = table.NewRow();
// populate data row with values here
ListBox test = new ListBox();
myTabPage.Controls.Add(test);
table.Rows.Add(dr);
}
return table;
}
And here is how I create the datagridview.
private void createGridInForm(int rows, int columns)
{
DataGridView RunTimeCreatedDataGridView = new DataGridView();
RunTimeCreatedDataGridView.DataSource = createGridForForm(rows, columns);
//DataGridViewColumn ID_Column = RunTimeCreatedDataGridView.Columns[0];
//ID_Column.Width = 200;
int positionForTable = getLocationForTable();
RunTimeCreatedDataGridView.BackgroundColor = Color.WhiteSmoke;
RunTimeCreatedDataGridView.Size = new Size(995, 200);
RunTimeCreatedDataGridView.Location = new Point(5, positionForTable);
myTabPage.Controls.Add(RunTimeCreatedDataGridView);
}
You were right on track with your first code block... the problem was you were trying to add a column to a cell reference. If you want to add a column where all rows have a drop down, then do exactly what you were doing, but simply add the column instead of specifying a cell value, like this:
var column = new DataGridViewComboBoxColumn();
RunTimeCreatedDataGridView.Columns.Add(column);
Then, specify the datasource as you normally would for a combobox.
Alternatively, if you want a specific cell to have a different combobox, or only a single cell in the column to have one, you can create a separate one as shown here or here.
Edit: To add a combobox to a specific cell in the DataGridView, you would do something like this:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
DataGridView dgv = new DataGridView();
// add some columns and rows
for (int i = 0; i < 10; i++)
{
DataGridViewCell c = new DataGridViewHeaderCell();
dgv.Columns.Add("Column" + i, Convert.ToString(i));
}
for (int i = 0; i < 10; i++)
{
dgv.Rows.Add(new DataGridViewRow());
}
//create a new DataGridViewComboBoxCell and give it a datasource
var DGVComboBox = new DataGridViewComboBoxCell();
DGVComboBox.DataSource = new List<string> {"one", "two", "three"};
DGVComboBox.Value = "one"; // set default value of the combobox
// add it to cell[4,4] of the DataGridView
dgv[4, 4] = DGVComboBox;
// add the DataGridView to the form
this.Controls.Add(dgv);
}
}

Reset column increment datagridview

I am trying to update the row increment number in a DataGridView in my WinForms application after deleting a row or rows. I have looked at sources and the all point on how to add the incrementing to a column in DataTable. My DataGridView is bound to my DataTable, and that is bound to a DataSet.
How I created by datatable:
DataColumn itemNumber = new DataColumn();
itemNumber.ColumnName = "ItemNumber";
itemNumber.AutoIncrement = true;
itemNumber.AutoIncrementSeed = 1;
itemNumber.AutoIncrementStep = 1;
DataColumn article = new DataColumn();
article.ColumnName = "Article";
article.ReadOnly = true;
DataColumn description = new DataColumn();
description.ColumnName = "Description";
description.ReadOnly = true;
DataColumn type = new DataColumn();
type.ColumnName = "Type";
type.ReadOnly = true;
//add to datatable
dt.Columns.Add(itemNumber);
dt.Columns.Add(article);
dt.Columns.Add(description);
dt.Columns.Add(type);
Removing a row from the DataGridView
foreach (DataGridViewRow row in dgvView.SelectedRows)
{
dgvView.Rows.RemoveAt(row.Index);
}
If I have 5 rows, and delete one. I would like the increment values to start from the 1,2,3,4 etc...
Can someone point me on how to achieve this?
I can't think of an efficient way to do this, but here are some ideas that may work with small data sets.
Keep up with the values yourself
1) Don't define the column as an AutoIncrement column):
DataColumn itemNumber = new DataColumn();
itemNumber.ColumnName = "ItemNumber";
//itemNumber.AutoIncrement = true;
//itemNumber.AutoIncrementSeed = 1;
//itemNumber.AutoIncrementStep = 1;
2) Handle the DataGridView.RowsAdded and DataGridView.RowsRemoved events and "reset" the values:
private void dgvView_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
if (dgvView.Columns.Contains("ItemNumber"))
{
foreach (DataGridViewRow r in dgvView.Rows)
{
r.Cells["ItemNumber"].Value = r.Index + 1;
}
}
}
private void dgvView_RowsRemoved(object sender, DataGridViewRowsRemovedEventArgs e)
{
if (dgvView.Columns.Contains("ItemNumber"))
{
foreach (DataGridViewRow r in dgvView.Rows)
{
r.Cells["ItemNumber"].Value = r.Index + 1;
}
}
}
Regenerate the values by rebuilding the DataTable and rebinding to it
1) Define the helper method below:
private DataTable ResetAutoIncrementColumn(DataTable dt, string autoIncrementColumnName)
{
DataTable result = new DataTable();
DataColumn itemNumber = new DataColumn(autoIncrementColumnName);
itemNumber.AutoIncrement = true;
itemNumber.AutoIncrementSeed = 1;
itemNumber.AutoIncrementStep = 1;
result.Columns.Add(itemNumber);
dt.Columns.Remove(autoIncrementColumnName);
result.Merge(dt, true);
return result;
}
2) Call it at the appropriate time (e.g. after a series of deletes as in the original question):
dt = ResetAutoIncrementColumn(dt, "ItemNumber");
dt.Columns["ItemNumber"].SetOrdinal(0);
dgvView.DataSource = dt;
dgvView.Columns["ItemNumber"].DisplayIndex = 0;
If you are just looking for a visual row number
Also, if you are just looking to have a visual row number on the DataGridView (and you don't care about the value being present in the underlying DataTable), you can handle the DataGridView.RowPostPaint event as follows (pulled from https://stackoverflow.com/a/12840794/3085273):
private void dgGrid_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
var grid = sender as DataGridView;
var rowIdx = (e.RowIndex + 1).ToString();
var centerFormat = new StringFormat()
{
// right alignment might actually make more sense for numbers
Alignment = StringAlignment.Center,
LineAlignment = StringAlignment.Center
};
var headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height);
e.Graphics.DrawString(rowIdx, this.Font, SystemBrushes.ControlText, headerBounds, centerFormat);
}

How do you make the header row unselectable in a table that was imported into a dataGridView

When the data loads into the dataGridView, if you click on the header column name of a particular column, it will re sort all the data in that column alphabetically. How do I make it so you can't do that?
This is the code which builds the individual dataGrids, each on its own tab.
var tabPage = new TabPage(name1);
DataGridView grid = new DataGridView(); //{ //Dock = DockStyle.Fill // };
grid.Location = new Point(10, 50);
grid.Size = new Size(950, 450);
grid.Name = "dg_" + name;
tabPage.Controls.Add(grid);
grid.ScrollBars = ScrollBars.Both;
grid.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader;
comboBox1.Items.Add(name1);
tabControl2.TabPages.Add(tabPage);
loadData(name, grid);
If I understand you right, run this loop apter you populate your grid with data. THis will set the columns not sortable
foreach (DataGridViewColumn col in dataGridView1.Columns)
{
col.SortMode = DataGridViewColumnSortMode.NotSortable;
}
for datagridview there is a enumerator called DataGridViewColumnSortMode.by this you can sort out your problem
for (int m = 0; m <= dataGridView1.ColumnCount-1; m++)
dataGridView1.Columns[m].SortMode = DataGridViewColumnSortMode.NotSortable;
Refer this link

Copy Data Table to a Data Grid without binding them together

I have two datagrids in my application (dataGridView1 and dataGridView2). I am moving selected items from dataGridView1 into dataGridView2. Here is how I am currently doing this:
DataTable dt = new DataTable("dt");
DataTable id = new DataTable("id");
try
{
if (dataGridView1.Rows.Count > 0)
{
for (int i = 0; i < dataGridView1.Rows.Count - 0; i++)
{
if (dataGridView1.Rows[i].Cells[0].Value != null)
{
DataRow row;
DataRow idRow;
row = dt.NewRow();
idRow = id.NewRow();
idRow["id"] = dataGridView1.Rows[i].Cells[1].Value.ToString();
row["id"] = dataGridView1.Rows[i].Cells[1].Value.ToString();
row["Link Name"] = dataGridView1.Rows[i].Cells[2].Value.ToString();
dt.Rows.Add(row);
id.Rows.Add(idRow);
}
}
dataGridView2.DataSource = dt;
}
However, I also need to be able to remove items from dataGridView2. Currently, the DataTable dt is bound to dataGridView2 and I cant clear it after the items are added because it also clears the dataGridView2.
Basicly, my question would be, is there a way to add the contents of a data table to a data grid without using datagrid.DataSource?
You can manually add each row using the dataGridView2.Rows.Add function. Also, I have typically used the dataGridView2.Row(n).Tag to hold the actual source of that row's data.
int n = dataGridView2.Rows.Add();
DataGridViewRow newRow = dataGridView2.Rows[n];
newRow.Cells[0].Value = "ABC";
newRow.Cells[1].Value = 123;
newRow.Tag = row;

Categories