Autosize and fit gridview columns - c#

i have a user form that contain some textbox and a grid view. my grid view contain 5 columns, what i am trying to is to autofit the first 4 columns and make the last one fill the remaining space available. i tried setting my first 4 columns auto Displayed Cells, AllCells.. and the last one to fill it work fine if the containing data in the first 4 columns don't exceed the column width, once they exceed the last column go out of bound.
Result:
Any help will be much appreciated

If you just need to make all the columns visible and you don't care about truncating the string with "...", just add this in the code (for example in the Load event of the form or in the Draw event of the GridView):
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
If, on the other hand, you want to have the cell string in its entirety, you could programmatically decrease the cell font, it is not exactly aesthetic but I leave you a code as an example (obviously it must be used together with the code I wrote above):
private void AdaptCellsToDataGrid()
{
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
foreach (DataGridViewRow row in dataGridView1.Rows)
{
bool ContentTruncated = true;
DataGridViewCell cell = dataGridView1.Rows[row.Index].Cells[column.Index];
cell.Style.Font = dataGridView1.Font;
Font currentCellFont = cell.Style.Font;
float currentFontSize = currentCellFont.Size;
float reduce = 1; //start with only 1 size reduction
while (ContentTruncated == true)
{
Graphics graphics = this.CreateGraphics();
//measuring the string lenght at drawing
SizeF sizeF = graphics.MeasureString(cell.Value.ToString(), dataGridView1.Font);
float textLength = sizeF.Width;
if (textLength > cell.Size.Width)
{
if ((currentFontSize - reduce) > 5) //if value is bigger than 5 reduce else stop reducing
{
cell.Style.Font = new Font(currentCellFont.FontFamily, (currentFontSize - reduce), currentCellFont.Style);
reduce = reduce + 1;
}
else
{
break;
}
}
else if (textLength <= cell.Size.Width)
{
ContentTruncated = false;
break;
}
}
}
}
}
I hope I have helped you in some way. :)

Related

RowSizingAutoMaxLines one row Ultragrid Infragistics

I am using this code, it is a bad example, but it works to test, but it ends up changing all rows.
I need only change the row selected.
if (e.Cell.Column.Layout.Override.RowSizingAutoMaxLines == 4)
{
e.Cell.Column.Layout.Override.RowSelectorStyle = Infragistics.Win.HeaderStyle.XPThemed;
e.Cell.Column.Layout.Override.RowSizingAutoMaxLines = 20;
}
else
{
e.Cell.Column.Layout.Override.RowSelectorStyle = Infragistics.Win.HeaderStyle.Default;
e.Cell.Column.Layout.Override.RowSizingAutoMaxLines = 4;
}
Setting the RowSizingAutoMaxLines on Override will set this to all the rows. What you can do instead is calculate the necessary row height and set it to the current row, assuming you have set beforehand RowSizing to Free or to AutoFree. You can use Graphics MeasureString to calculate the height of one row and set then each row's height like this:
First setup the grid:
private void UltraGrid1_InitializeLayout(object sender, InitializeLayoutEventArgs e)
{
// I think you need row selectors as you set their style
e.Layout.Override.RowSelectors = Infragistics.Win.DefaultableBoolean.True;
// Set the RowSizing to some Free value to allow each row to has its onw height
e.Layout.Override.RowSizing = RowSizing.AutoFree;
// I think you have multiline text in the cells, so you should set CellMultiLine to true too
e.Layout.Override.CellMultiLine = Infragistics.Win.DefaultableBoolean.True;
}
Then measure one row and set the row's height:
// Calculate the height of one line of text
var oneLineHeight = float.MinValue;
using(Graphics g = this.ultraGrid1.CreateGraphics())
{
oneLineHeight = g.MeasureString("Jj", this.ultraGrid1.Font, int.MaxValue, StringFormat.GenericTypographic).Height;
}
// Set the row selectors' style and the row's height
if(e.Cell.Column.Layout.Override.RowSelectorStyle == Infragistics.Win.HeaderStyle.Default)
{
e.Cell.Column.Layout.Override.RowSelectorStyle = Infragistics.Win.HeaderStyle.XPThemed;
// Add 4 to add some padding
e.Cell.Row.Height = (int)(oneLineHeight * 20 + 4);
}
else
{
e.Cell.Column.Layout.Override.RowSelectorStyle = Infragistics.Win.HeaderStyle.Default;
// Add 4 to add some padding
e.Cell.Row.Height = (int)(oneLineHeight * 4 + 4);
}

How to vertically auto size a winforms datagridview control, so that its rows are always visible

I have a DataGridView that displays a limited number of rows, never more than 5. This DataGridViewis placed on a DataRepeater control so it's usually displayed many times on the screen. What I want to achieve is that all grids are resized to the size of their contents so they don't display scroll bars if 4 or 5 items are in them or take up extra vertical space if only 1 or 2 items are there.
The grids only contain text data. They are data bound controls, so they'll need to resize if the underlying data source changes (I guess the DataBindingComplete event would be suitable).
How may I achieve this? Is counting rows the best option? Thanks in advance.
Since your control is data-bound, I would set the Height property on the DataGridView to the sum of the heights of its rows (plus some margin) in the DataBindingComplete event:
private void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
var height = 40;
foreach (DataGridViewRow dr in dataGridView1.Rows) {
height += dr.Height;
}
dataGridView1.Height = height;
}
I took hmqcnoesy's answer and expanded on it and created a function to also include the width. And to use on any grid.
Note: Set AutoSizeCells = AllCells on the grid.
public static DataGridView SetGridHeightWidth(DataGridView grd, int maxHeight, int maxWidth)
{
var height = 40;
foreach (DataGridViewRow row in grd.Rows)
{
if(row.Visible)
height += row.Height;
}
if (height > maxHeight)
height = maxHeight;
grd.Height = height;
var width = 60;
foreach (DataGridViewColumn col in grd.Columns)
{
if (col.Visible)
width += col.Width;
}
if (width > maxWidth)
width = maxWidth;
grd.Width = width;
return grd;
}
This value can be anything. You should test in your grid to discover what's the best value to set the height.
var height = 40;
Edited:
To find the real value to height, you need add the location of grid and height of header. Something like that.
int height = dgv.Location.Y + dgv.ColumnHeadersHeight;
foreach (DataGridViewRow dr in dgv.Rows) {
height += dr.Height; // Row height.
}
dgv.Height = height;

How to set the back color of the row / column header cell in a datagridview - c# winform

I want to set the back color of the row header and column header intersection cell of a datagridview. I tried the below code, but it throws an exception that the number should be non negative.
DataGridViewCell cell = dgview.Rows[-1].Cells[-1];
cell.Style.BackColor = Color.Red;
I want to set the color as shown in the image below
I also refered the below article, but it shows how to set the color of the whole column header. But my requirement is to set the color of a single cell - row-column header intersection cell.
how-to-change-the-color-of-winform-datagridview-header
Any help is much appreciated. Thank you.
Regards,
Vinay
Store the current ColumnHeadersDefaultCellStyle in a variable.
Set the ColumnHeadersDefaultCellStyle to how you want the corner to be.
Then change all of the columns headers to how you want columns 0 to ... back to the old style.
Below is an example where the form is called "MyForm". This example shows the default constructor of MyForm.
Example:
public MyForm()
{
InitializeComponent();
// insert code here to add columns ...
// ...
// ...
// ...
DataGridViewCellStyle oldDefault = dgview.ColumnHeadersDefaultCellStyle.Clone();
dgview.ColumnHeadersDefaultCellStyle.BackColor = Color.Red;
foreach (DataGridViewColumn item in dgview.Columns)
{
item.HeaderCell.Style = oldDefault;
}
}
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == -1 && e.ColumnIndex == -1)
{
using (Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor))
{
using (Brush backColorBrush = new SolidBrush(Color.Red))
{
using (Pen gridLinePen = new Pen(gridBrush))
{
// Clear cell
e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
//Bottom line drawing
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom-1 , e.CellBounds.Right, e.CellBounds.Bottom-1);
e.Handled = true;
}
}
}
}
This is a bit of a hack, but add a PictureBox inside the DataGridView using the designer(if you're using VS) and initialize it's properties such as:
pictureBox1.BackColor = Color.Red;
pictureBox1.Width = dgView.RowHeadersWidth;
pictureBox1.Height = dgView.ColumnHeadersHeight;

c# resize datagridview columns to fit control

I have a datagridview that is docked and anchored with a panel on a Winform. When I resize the form, the datagridview resizes as expected, but the columns do not resize to fit the datagridview. Instead, I am left with the background colour of the Datagridview.
How can I get the columns to grow with the control?
Thanks.
You could always use the AutoSizeColumnsMode property
This property lets you configure the control so that column widths are automatically adjusted either to fill the control or to fit cell contents. Size adjustments occur in fill mode whenever the width of the control changes.
There's a lot more information on the MSDN page for this.
You can set AutoSizeMode property of one of the columns to be Fill. Then this column will always resize itself to fill all the available space not used by other columns.
private void dataGrid_SizeChanged(object sender, EventArgs e)
{
ResizeGridColumns();
}
private void ResizeGridColumns()
{
//get sum of non-resizable columns width
int diffWidth = 0;
foreach (DataGridViewColumn col in this.dataGrid.Columns)
{
if (col.Resizable == DataGridViewTriState.False && col.Visible) diffWidth += col.Width;
}
//calculate available width
int totalResizableWith = this.dataGrid.Width - diffWidth;
//resize column width based on previous proportions
this.dataGrid.ColumnWidthChanged -= new DataGridViewColumnEventHandler(dataGrid_ColumnWidthChanged);
for (int i = 0; i < this.colWidthRaport.Count; i++)
{
try
{
if (this.dataGrid.Columns[i].Resizable != DataGridViewTriState.False && this.dataGrid.Columns[i].Visible)
{
this.dataGrid.Columns[i].Width = (int)Math.Floor((decimal)totalResizableWith / this.colWidthRaport[i]);
}
}
catch { }
}
this.dataGrid.ColumnWidthChanged += new DataGridViewColumnEventHandler(dataGrid_ColumnWidthChanged);
}
private void dataGrid_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
CalculateGridColWidthsRaport();
}
/// <summary>Calculates the proportions between grid width and column width</summary>
private void CalculateGridColWidthsRaport()
{
//get sum of non-resizable columns width
int diffWidth = 0;
int colWidthsSum = 0;
foreach (DataGridViewColumn col in this.dataGrid.Columns)
{
if (col.Visible)
{
colWidthsSum += col.Width;
if (col.Resizable == DataGridViewTriState.False) diffWidth += col.Width;
}
}
colWidthsSum += 24;
//calculate available with
int totalResizableWith = colWidthsSum - diffWidth;// this.dataGrid.Width - diffWidth;
if (this.ParentForm.WindowState == FormWindowState.Maximized)
{
totalResizableWith = this.dataGrid.Width - diffWidth;
}
//calculate proportions of each column relative to the available width
this.colWidthRaport = new List<decimal>();
foreach (DataGridViewColumn col in this.dataGrid.Columns)
{
this.colWidthRaport.Add((decimal)totalResizableWith / (decimal)col.Width);
}
}

Changing the row height of a DataGridView

How can I change the row height of a DataGridView?
I set the value for the property but height doesn't change. Any other property has to be checked before setting this one.
You need to set the Height property of the RowTemplate:
var dgv = new DataGridView();
dgv.RowTemplate.Height = 30;
You can set the row height by code:
dataGridView.RowTemplate.Height = 35;
Or in the property panel:
Note the + sign to the left of the Row Template section name. You need to open it to see the Height field. By default it is closed.
Try
datagridview.RowTemplate.MinimumHeight = 25;//25 is height.
I did that and it worked fine!
you can do that on RowAdded Event :
_data_grid_view.RowsAdded += new System.Windows.Forms.DataGridViewRowsAddedEventHandler(this._data_grid_view_RowsAdded);
private void _data_grid_view_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
{
_data_grid_view.Rows[e.RowIndex].Height = 42;
}
when a row add to the dataGridView it just change it height to 42.
You also need to change the resizable property to true
dataGridView1.RowTemplate.Resizable = DataGridViewTriState.True;
dataGridView1.RowTemplate.Height = 50;
You need to :
dataGridView1.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
Then :
dataGridView1.ColumnHeadersHeight = 60;
You can change the row height of the Datagridview in the
.cs [Design].
Then click the datagridview Properties.
Look for RowTemplate and expand it,
then type the value in the Height.
What you have to do is to set the MinimumHeight property of the row. Not only the Height property. That's the key. Put the code bellow in the CellPainting event of the datagridview
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
foreach(DataGridViewRow x in dataGridView1.Rows)
{
x.MinimumHeight = 50;
}
}
dataGridView1.AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.AllCells;
for (int i = 0; i < dataGridView1.Columns.Count; i++)
{
dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
dataGridView1.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.NotSet;
}
Make sure AutoSizeRowsMode is set to None else the row height won't matter because well... it'll auto-size the rows.
Should be an easy thing but I fought this for a few hours before I figured it out.
Better late than never to respond =)
this worked for me
int totalRowHeight = dataGridView1.ColumnHeadersHeight;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
totalRowHeight += row.Height;
}
if (totalRowHeight < dataGridView1.Height)
{
totalRowHeight = dataGridView1.Height;
totalRowHeight -= dataGridView1.ColumnHeadersHeight;
int rowHeight = totalRowHeight / dataGridView1.Rows.Count;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
row.MinimumHeight = rowHeight;
}
dataGridView1.Refresh();
}
try simply:
dataGrid->Rows[i]->Height = 20;

Categories

Resources