I have a DataGridView which I put on a form using the designer. I'm trying to display some data by programmatically creating rows. The code is below. This DataGridView displays nothing at all, it might as well be an empty label or panel. I've looked at other questions regarding empty DataGridViews and tried all the suggestions. One common suggestion is "Just set AutoGenerateColumns to true, it will solve the problem." That did not work. I've tried implementing a DataTable and binding to the DataSource on the DataGridView. That did not work either.
Using the debugger in VisualStudio, I tried looking at the row properties/column properties/cell properties (within each row). The row and cell properties both have a "Displayed" property, which is set to false. This seems to be a read-only property, I can't set it to true (I get an error when I try). Apparently this property can be set to true or false to show or hide rows or cells, but I can't set it to anything.
After trying a lot of things, I ended up with the minimal test code below, which should work, but still doesn't.
What am I doing wrong?
int M = 2, N = 2;
dgvSpreadSheet.AutoGenerateColumns = true;
dgvSpreadSheet.ColumnCount = N;
dgvSpreadSheet.Rows.Clear();
for (int ix = 0; ix < N; ix++)
dgvSpreadSheet.Columns[ix].Name = "Column " + (ix + 1).ToString();
for (int ix = 0; ix < M; ix++)
{
string[] row = new string[N];
for (int j = 0; j < N; j++)
{
row[j] = "Test";
}
dgvSpreadSheet.Rows.Add(row);
dgvSpreadSheet.Rows[ix].HeaderCell.Value = "Header" + (ix + 1).ToString();
}
dgvSpreadSheet.RowHeadersWidth = 200;
dgvSpreadSheet.RowHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.True;
dgvSpreadSheet.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dgvSpreadSheet.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
Related
I am having a formatting issue when exporting my data table to Excel. The data is exported as it should, however if you look at my image, sometimes the cell height is increased and I am not sure why. I want the data to look the same from row to row. This is the syntax I am using to export
for (var i = 0; i < tbl.Columns.Count; i++)
workSheet.Cells[1, i + 1] = tbl.Columns[i].ColumnName;
for (var i = 0; i < tbl.Rows.Count; i++)
{
for (var j = 0; j < tbl.Columns.Count; j++)
workSheet.Cells[i + 2, j + 1] = tbl.Rows[i][j];
}
And here is an image that shows my formatting issues that I want to find a way to overcome. Can someone show me what syntax I need in order to have all row height/width the same?
Issue Image
EDIT
I tried this, but it throws an error and does not format as needed
The error is
System.Exception
Excel.Range range1 = workSheet.get_Range("A2", "S2000");
range1.EntireRow.Height.Value = 15;
You are over complicating it. Just use the UsedRange property. If workSheet is your actual variable name and 15 is the actual height you want to set, the below will work:
workSheet.UsedRange.EntireRow.RowHeight = 15;
Is it possible to update style for all cells from DataGridView without iteration over them like example below?
for (int i = 0; i < dgv.Columns.Count; i++)
for (int j = 0; j < dgv.Rows.Count; j++)
if (dgv[i, j].Style != style)
dgv[i, j].Style = style;
My question is an actual due to slow speed of slyle updating for all cells.
If you want to apply the same style to all the cells, simply use the DefaultCellStyle of the datagridview.
dataGridView.DefaultCellStyle.BackColor = Color.Green;
The answer of Killercam would be helpful when you want to apply different styles to different cells on the same rows.
You can do this on a row-by-row basis:
foreach (DataGridViewRow row in dataGridView.Rows)
Row.DefaultCellStyle.BackColor = Color.Red;
or
for (int r = 0; r < dataGridView.Rows.Count; r++)
dataGridView.Rows[r].DefaultCellStyle.BackColor = Color.Red;
where using the DefaultCellStyle you can set other properties as well.
I hope this helps.
I'd like to design an interface showing buttons in a data grid - for each day and its 24 hours. All in all we'll be showing: 24 * 7 = 168 buttons.
Any idea how to accomplish this?
I did an example code of how it ca ne done!
This code only creates the buttons, so check it out:
note: name buttons your own way, I only did an example!
dataGridView1.AllowUserToAddRows = false;
for (int i = 0; i < 24; i++)
{
DataGridViewButtonColumn btnColumn = new DataGridViewButtonColumn();
btnColumn.HeaderText = string.Format("{0}:00", i+1);
btnColumn.Name = "dayColumn";
btnColumn.Width = 40; //set yout width
dataGridView1.Columns.Add(btnColumn);
}
for (int i = 0; i < 7; i++)
{
dataGridView1.Rows.Add();
dataGridView1.Rows[i].HeaderCell.Value = (i + 1).ToString();
for (int j = 0; j < dataGridView1.Columns.Count; j++)
{
dataGridView1[j, i].Value = string.Format("{0}:00", (j + 1));
}
}
--
Maybe subscribing to an event handler, when some button is clicked is a good idea:
public Form1()
{
InitializeComponent();
dataGridView1.AllowUserToAddRows = false;
for (int i = 0; i < 24; i++)
{
DataGridViewButtonColumn btnColumn = new DataGridViewButtonColumn();
btnColumn.HeaderText = string.Format("{0}:00", i+1);
btnColumn.Name = "dayColumn";
btnColumn.Width = 40; //set yout width
dataGridView1.Columns.Add(btnColumn);
}
for (int i = 0; i < 7; i++)
{
dataGridView1.Rows.Add();
dataGridView1.Rows[i].HeaderCell.Value = (i + 1).ToString();
for (int j = 0; j < dataGridView1.Columns.Count; j++)
dataGridView1[j, i].Value = string.Format("{0}:00", (j + 1));
}
dataGridView1.CellClick += new DataGridViewCellEventHandler(dataGridView1_CellClick);
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
string day = dataGridView1.Rows[e.RowIndex].HeaderCell.Value.ToString();
string hour = dataGridView1.Columns[e.ColumnIndex].HeaderText.ToString();
MessageBox.Show("you have clciked on day: " + day + ", hour: " + hour);
}
There is a framework interface called ITypedList which allows you to directly specify properties to be displayed for each constituent member, in a way that databinding understands.
Realise that attempting to do binding in this way is absolutely hideous. The basic steps are as follows:
Implement a collection type that implements ITypedList;
For each item in the collection, return a PropertyDescriptor which encapsulates the value of the row/column pair;
Databind to the collection as normal
I've done this as an experiment and it works, but the hoops you'll have to jump through to get everything to work properly are a nightmare. Still, I'd usually consider it better than manipulating view logic directly. DataGridView is meant to be intelligent enough to infer everything it needs to do from binding, and if I can modify the binding target rather than the control, that's what I'd prefer.
In C# Winforms, I'd like to use a DataGridView as a simple widget to store information to display to the user. To this end, I'd like to create a table of say, 5x10 cells.
After some research, solutions tend to allow adding just one row or column at a time. I'd like the whole grid created initially and straight away, so I can start populating it with data, like you would with a standard C# 2D array.
What's the simplest way of going about this? A function header could look like this:
createCells(DataGridView dgv, int cols, int rows) {}
It should be quick and amenable to changing the cols and rows to a larger or smaller number later on if need be.
By the way, there might an error like:
Sum Of The Columns' FillWeight Values Cannot Exceed 65535
To avoid it, set AutoGenerateColumns property to false, and set FillWeight to 1 for each column generated:
dgv.AutoGenerateColumns = false;
for (int i = 1; i <= columns; i++)
{
dgv.Columns.Add("col" + i, "column " + i);
dgv.Columns[i - 1].FillWeight = 1;
}
for (int j = 0; j < rows; j++)
dgv.Rows.Add();
You can do by using for loops in this way:
private DataGridView DGV_Creation(DataGridView dgv, int columns, int rows)
{
for (int i = 1; i <= columns; i++)
{
dgv.Columns.Add("col" + i, "column " + i);
}
for (int j = 0; j < rows; j++)
{
dgv.Rows.Add();
}
return dgv;
}
Call it with:
this.dataGridView1 = DGV_Creation(dataGridView1, 5, 10); // 5 columns, 10 rows (empty rows)
or:
private void DGV_Creation(ref DataGridView dgv, int columns, int rows)
{
for (int i = 1; i <= columns; i++)
dgv.Columns.Add("col" + i, "column " + i);
for (int j = 0; j < rows; j++)
dgv.Rows.Add();
}
call it with:
DGV_Creation(ref this.dataGridView1, 5, 10); //5 columns, 10 rows (empty rows)
What is wrong with this code
for (int i = 1; i < dgv.Rows.Count;)
{
MessageBox.Show(dgv.Rows[i].Index.ToString());
}
I'm getting endless MsgBoxes displaying allways and only value "1"
dgv has six rows.
you forget to place i++
and also i = 0; if i = 1 you will be miss first row of gridview
for (int i = 0; i < dgv.Rows.Count;i++)
{
MessageBox.Show(dgv.Rows[i].Index.ToString());
}