I have 3 columns in my DataGridView. What I am trying to do is have the first 2 columns auto fit to the width of the content, and have the 3rd column fill the remaining space.
Is it possible to do in WinForms? I am loading my data from an EF DataContext if that's any use. I have included an image of how it currently looks.
You need to use the DataGridViewColumn.AutoSizeMode property.
You can use one of these values for column 0 and 1:
AllCells: The column width adjusts to fit the contents of all cells in
the column, including the header cell.
AllCellsExceptHeader: The column width adjusts to fit the contents of all cells in the column, excluding the header cell.
DisplayedCells: The column width adjusts to
fit the contents of all cells in the column that are in rows currently
displayed onscreen, including the header cell.
DisplayedCellsExceptHeader: The column width adjusts to fit the
contents of all cells in the column that are in rows currently
displayed onscreen, excluding the header cell.
Then you use the Fill value for column 2
The column width adjusts so that the widths of all columns exactly fills the display area of the control...
this.DataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
As pointed out by other users, the default value can be set at datagridview level with DataGridView.AutoSizeColumnsMode property.
this.DataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
this.DataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
could be:
this.DataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
Important note:
If your grid is bound to a datasource and columns are auto-generated (AutoGenerateColumns property set to True), you need to use the DataBindingComplete event to apply style AFTER columns have been created.
In some scenarios (change cells value by code for example), I had to call DataGridView1.AutoResizeColumns(); to refresh the grid.
This is my favorite approach...
_dataGrid.DataBindingComplete += (o, _) =>
{
var dataGridView = o as DataGridView;
if (dataGridView != null)
{
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dataGridView.Columns[dataGridView.ColumnCount-1].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
};
Just change Property from property of control:
AutoSizeColumnsMode:Fill
OR By code
dataGridView1.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.Fill;
Not tested but you can give a try. Tested and working. I hope you can play with AutoSizeMode of DataGridViewColum to achieve what you need.
Try setting
dataGridView1.DataSource = yourdatasource;<--set datasource before you set AutoSizeMode
//Set the following properties after setting datasource
dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
This should work
Try doing,
AutoSizeColumnMode = Fill;
public static void Fill(DataGridView dgv2)
{
try
{
dgv = dgv2;
foreach (DataGridViewColumn GridCol in dgv.Columns)
{
for (int j = 0; j < GridCol.DataGridView.ColumnCount; j++)
{
GridCol.DataGridView.Columns[j].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
GridCol.DataGridView.Columns[j].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
GridCol.DataGridView.Columns[j].FillWeight = 1;
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
To build on AlfredBr's answer, if you hid some of your columns, you can use the following to auto-size all columns and then just have the last visible column fill the empty space:
myDgv.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
myDgv.Columns.GetLastColumn(DataGridViewElementStates.Visible, DataGridViewElementStates.None).AutoSizeMode =
DataGridViewAutoSizeColumnMode.Fill;
This is what I have done in order to get the column "first_name" fill the space when all the columns cannot do it.
When the grid goes to small the column "first_name" gets almost invisible (very thin) so I can set the DataGridViewAutoSizeColumnMode property to AllCells as the others visible columns. For performance issues it's important to set them to None before data binding it and set back to AllCells in the DataBindingComplete event handler of the grid. Hope it helps!
private void dataGridView1_Resize(object sender, EventArgs e)
{
int ColumnsWidth = 0;
foreach(DataGridViewColumn col in dataGridView1.Columns)
{
if (col.Visible) ColumnsWidth += col.Width;
}
if (ColumnsWidth <dataGridView1.Width)
{
dataGridView1.Columns["first_name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
else if (dataGridView1.Columns["first_name"].Width < 10)
{
dataGridView1.Columns["first_name"].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
}
public void setHeight(DataGridView src)
{
src.Height= src.ColumnHeadersVisible ? src.ColumnHeadersHeight : 0 + src.Rows.OfType<DataGridViewRow>().Where(row => row.Visible).Sum(row => row.Height);
}
Try this :
DGV.AutoResizeColumns();
DGV.AutoSizeColumnsMode=DataGridViewAutoSizeColumnsMode.AllCells;
Related
I have a DataGridView in my WinForms application. Basically, I want to input some 2D data there or something like that. It means, that I want to have both columns named and rows named. And so I did. But then there was a problem. When it's fine with column names, the row names tend to be not visible. For example:
The code I use to somehow "beautify" the DataGridView:
private void BeautifyTable(TableView tableView)
{
foreach (DataGridViewRow row in tableView.Rows)
{
row.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
}
foreach (DataGridViewColumn col in tableView.Columns)
{
col.HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
col.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
}
}
TableView is a class created by me, and it inherits from DataGridView.
So now my question would be: Is there a way to somehow make those row names/titles appear in a normal way (in this particular case those are: s0, s1, s2.., but they're like cut from the left side).
P.S Is there a good way to "stretch" the columns? I mean if I have f.e 10 columns they would fill the whole DataGridView width, but if I would add (I do this dynamically) 5, so there would be 15 columns, still they would fit, just the width of every column would decrease?
Increase the width of the row header:
dataGridView1.RowHeadersWidth =
dataGridView1.RowHeadersWidth * 2; // or another value
Try to hide those arrows by setting the RowHeadersVisible to False in the properties of the datagridview at the Form.cs [Design] or just simply add the code below.
Me.DataGridView1.RowHeadersVisible = False
I actually found the best answer by myself.
You can set the WitdthSizeMode also for row headers, like this:
tableView.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders;
And that's the result:
I have an issue creating DataGridView and combobox in windows form application. I need help in writing the code with a condition when combobox value is clicked, datagridview column header will change adjusting with the selected combobox value. Here is the example picture of my desired application:
Example datagridview when wages is selected
Example datagridview when sales is selected
Thank you for your time and help :D
if (comboBox1.SelectedItem == "Wages")
{
dataGridView1.ColumnCount = 3;
dataGridView1.Columns[0].Name = "StoreLoc";
dataGridView1.Columns[1].Name = "Month";
dataGridView1.Columns[2].Name = "Value";
}
else if (comboBox1.SelectedItem == "Sales")
{
dataGridView1.ColumnCount = 3;
dataGridView1.Columns[0].Name = "StoreName";
dataGridView1.Columns[1].Name = "StoreType";
dataGridView1.Columns[2].Name = "Value";
}
It is possible to have changed all properties (like column headers etc). I used it in an application I built, but if I would do it again, I would create two separate grid views, and make one of them visible depending on the combo box selection.
So something like (pseudo code):
void ComboBoxedValueChanged(...)
{
gridViewWages.IsVisible = (comboBoxValue == wages);
gridViewSales.IsVisible = (comboBoxValue == sales);
}
I have a datagridview that has two columns, what i want to do is iterate over the rows and colour only the second row based on a condition, so far i have this:
foreach (DataGridViewRow row in dsgDataGrid.Rows)
{
var stock = Convert.ToInt32(row.Cells[1].Value);
if (stock == 0)
{
row.DefaultCellStyle.BackColor = Color.Red;
}
if (stock >= 1 && stock <= 5)
{
row.DefaultCellStyle.BackColor = Color.LightSalmon;
}
}
That gets the entire row red (where the value is 0) but can anyone advise on how to only affect the cell in the second column based on the condition?
Thanks.
You can set the BackColor of a specific cell by using the Cells property of the DataGridViewRow with the desired index, for example:
row.Cells[2].Style.BackColor = Color.Red;
You can also use the name of column:
row.Cells["ColumnName"].Style.BackColor = Color.Red;
You'll be able to set the Color on a specific cell of a row with the following line of code:
row.Cells[1].Style.BackColor = Color.Red;
Or you could also loop through columns instead and set the color on each cell depending on the value of the cell your looking up.
How did they do this?
Is it AdvanceBandedGridView on Devexpress?
I tried using advbandedgridview but my Image Column wont Fill Fullsize.
im just simply set the Image repository to SizeMode = Stretch but seems only stretch on width but not on height.
Anyone could help me on this? please. thanks.
You just need to set icon column's AutoFillDown Property to true and RowCount Property to 2 or 3 depend on number of rows you have created in the view to display a particular row from data.
As per the documentation of BandedGridColumn.AutoFillDown Property, If you set it to true, then column header is automatically stretched to fill the empty space below it and RowCount remain unchanged to 1 until you do not specify the BandedGridColumn.RowCount Property.
Setting the RowCount property affects not only the column header's
height but the height of each cell within this column. The height of a
single data cell row, however, is specified by the GridView.RowHeight
property.
This is sample code from devExpress AdvancedBandedGridView sample app, which output image you have attached in your question:
//
// gridBand3
//
resources.ApplyResources(this.gridBand3, "gridBand3");
this.gridBand3.Columns.Add(this.colIcon);
this.gridBand3.OptionsBand.AllowSize = false;
this.gridBand3.OptionsBand.FixedWidth = true;
this.gridBand3.VisibleIndex = 2;
//
// colIcon
//
this.colIcon.AutoFillDown = true;
resources.ApplyResources(this.colIcon, "colIcon");
this.colIcon.ColumnEdit = this.repositoryItemPictureEdit1;
this.colIcon.FieldName = "Picture";
this.colIcon.Image = ((System.Drawing.Image)(resources.GetObject("colIcon.Image")));
this.colIcon.Name = "colIcon";
this.colIcon.OptionsColumn.AllowGroup = DevExpress.Utils.DefaultBoolean.False;
this.colIcon.OptionsColumn.AllowSize = false;
this.colIcon.OptionsColumn.AllowSort = DevExpress.Utils.DefaultBoolean.False;
this.colIcon.OptionsColumn.FixedWidth = true;
this.colIcon.OptionsFilter.AllowFilter = false;
this.colIcon.RowCount = 3;
Example:
View display based on these settings, here rows are 3, so RowCount property is set to 3 and AutoFillDown also set to true.
There are such an option for GridView and BandedGridView like GridOptionsView.RowAutoHeight property. But for AdvBandedGridView this property is not in effect. All you can do is use BandedGridColumn.RowCount property to increase the height of column cells:
advBandedGridView1.Columns["YourImageColumn"].RowCount = 3;
I have a DataGridView that gets a datasource assigned.
I would like to create my own columns if it's (for example) DateTime.
I found an example of how you can create a DateTimePicker (here) (and hopefully also a NumericUpDown) to add to the datagrid, but I don't know how i can define this column to my datagrid. Any help would be greatly appreciated!
Check the last method in your example:
private void Form1_Load(object sender, EventArgs e)
{
CalendarColumn col = new CalendarColumn();
this.dataGridView1.Columns.Add(col);
this.dataGridView1.RowCount = 5;
foreach (DataGridViewRow row in this.dataGridView1.Rows)
{
row.Cells[0].Value = DateTime.Now;
}
}
This is where the columns are added to the DataGridView. You can use the same way to add any column object derived from DataGridViewColumn to your grid.
[Edit]
Before binding, set the DataGridView.AutoGenerateColumns property to false and add your custom columns.
You will also have to set the DataPropertyName property for each column, to define which property will be bound to which column:
CalendarColumn col = new CalendarColumn();
col.DataPropertyName = "Date"; // if your class has a "Date" property
this.dataGridView1.Columns.Add(col);