Resize DataGridView - c#

I have a column that holds Checkboxes.
My main problem is that when I call this function:
dataGrid.AutoResizeColumn(0, DataGridViewAutoSizeColumnMode.DisplayedCells);
It stretches the checkbox column too, and I want that column to stay in 25 in width.
How can I do that? (only checkbox column not stretched)
Here is some more code, showing what I want to happen:
dataGrid.AutoResizeColumn(0, DataGridViewAutoSizeColumnMode.DisplayedCells);
dataGrid.AutoResizeColumn(1, DataGridViewAutoSizeColumnMode.Fill);
dataGrid.AutoResizeColumn(2, DataGridViewAutoSizeColumnMode.Fill);
dataGrid.AutoResizeColumn(3, DataGridViewAutoSizeColumnMode.DisplayedCells);
dataGrid.AutoResizeColumn(4, DataGridViewAutoSizeColumnMode.Fill);
dataGrid.AutoResizeColumn(5, DataGridViewAutoSizeColumnMode.Fill);
But the fill gives me an error.

What you are asking doesn't quite make sense, since the method you show AutoResizeColumn take as its first parameter the column index to resize - if you call this method with the index of the checkbox column then your are explicitly telling the grid to resize that column. If you don't want the resize, don't do that!
If you set the resize mode the next level up for the grid, you do it like this:
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells;
Now with this method of setting the sizing mode then yes, the checkbox will change when you might want it to.
The answer to that is to use either the designer or the method you mention above, and set the checkbox columns autosize mode to None
If you absolutely must loop over the columns setting their AutoResize mode, then the only option you have is to check if you have the checkbox column in the loop and apply a different more.
This is in answer to your comment - the error you will be seeing is an ArgumentException being thrown by the AutoResizeColumn method. This is all documented on the MSDN page for the AutoResizeColumn method. You cannot specify a AutoSize mode of None or Fill.
It sounds like what you want to do is something like:
// If column 3 is the checkbox column, we set its resize mode to none:
dataGridView1.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
// Then we set the width:
dataGridView1.Columns[3].Width = 25;
// Finally we set the rest of the grid to fill or what ever resizing you need:
dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;

you can define in datagridview_cellpainting event
private void gvDocumentList_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == gvDocumentList.Columns["checkbox column name"].Index && e.RowIndex >= 0)
{
e.PaintBackground(e.ClipBounds, true);
Rectangle rectRadioButton = new Rectangle();
rectRadioButton.Width = 14;
rectRadioButton.Height = 14;
rectRadioButton.X = e.CellBounds.X + (e.CellBounds.Width - rectRadioButton.Width) / 2;
rectRadioButton.Y = e.CellBounds.Y + (e.CellBounds.Height - rectRadioButton.Height) / 2;
e.Paint(e.ClipBounds, DataGridViewPaintParts.Focus);
e.Handled = true;
}
}

Related

Cannot remove spacing between controls in TableLayoutPanel?

There's some spacing between the Buttons I add to my TableLayoutPanel. I removed the border in the Button and set the Margin and Padding to 0 in the Panel. But I continue getting that spacing.
tableLayoutPanel.RowCount is set to 8 and the Rows collection I've added 8 rows with Size Type Absolute.
Am I missing something? Here's the code:
private void FillSelectLayout()
{
tableLayoutPanelSelect.Controls.Clear();
tableLayoutPanelSelect.RowStyles.Clear();
tableLayoutPanelSelect.RowCount = 8;
for (int i = 0; i < 8; i++)
{
Button buttonSelector = new Button();
buttonSelector.Height = 64;
buttonSelector.Width = 100;
buttonSelector.FlatStyle = FlatStyle.Flat;
buttonSelector.FlatAppearance.BorderSize = 0;
buttonSelector.BackColor = Color.Yellow;
tableLayoutPanelSelect.Controls.Add(buttonSelector, 0, i);
}
}
Here's how it's displayed:
To remove the space between buttons in cells, it's enough to set dock property of them to fill and then remove default margins of buttons:
var b = new Button();
b.Dock = DockStyle.Fill;
b.Margin = new Padding(0);
Note:
Usually it's better to set Dock property of controls which you host in cells to Fill. This way your controls will follow TableLayouPanel sizing rules which you set for columns and rows.
TableLayoutPanel use Margin property of control to set the location of control in cell. So If you don'n want to set Dock and you prefer to set the Size manually, it's enough to set the Margin only.
I .. set the Margin and Padding to 0 in the Panel.
Why didn't you remove the Margin in the Buttons instead:
buttonSelector.Margin = new Padding(0);
MSDN:
The Margin property defines the space around the control that keeps
other controls a specified distance from the control's borders.
I faced the same problem while using different control in TableLayoutPanel
You can do this
Go to Design View
Click on the properties
GoTo Columns, When you click text box besides Columns, a button (...) appears on extreme right, click it
A pop up window appears, Select AutoSize (Instead of Absolute or Percentage).
In the same window in Show: select Rows and again select Autosize.
Click okay and you are done.

Can a C# DataGridView cell be both Multiline and single line?

I'm building a DataGridView dynamically, and the textboxes potentially have an AutoComplete custom source associated with them. Under some circumstances, when I set textbox.Multiline to true, I get the following effect. If I'm not actively editing the cell, it looks like this:
However, if I try to edit the cell, it looks like this:
If I move the cursor around this edit mode cell, focus hops out of the cell entirely, instead of moving the text or expanding the cell height. It looks as if it's trying to be in multiline and single line mode at the same time, but I'm not sure.
Any thoughts?
I found a solution - not a root cause. In EditingControlShowing, I do the following:
textBox.Dock = textBox.Multiline ? DockStyle.Fill : DockStyle.None;
where I've set textBox = (TextBox) e.Control;
It's a sledgehammer solution, but it works.
Lets give a name to the DataGridView object: dgv,
So On dgv_CellEnter event add following lines
int idxcol = dgv.Columns["YourColumnName"].Index;
if (e.ColumnIndex == idxcol)
dgv.Columns[idxcol].DefaultCellStyle.WrapMode = DataGridViewTriState.False;
and on dgv_CellLeave event add the following lines
int idxcol = dgv.Columns["YourColumnName"].Index;
if (e.ColumnIndex == idxcol )
{
dgv.Columns[e.ColumnIndex].DefaultCellStyle.WrapMode = DataGridViewTriState.True;
}

Getting "No room is available to display rows" when setting gridView.FirstDisplayedScrollingRowIndex

gridView.FirstDisplayedScrollingRowIndex = gridView.SelectedRows[0].Index;
blowing up with:
No room is available to display rows
DataGridView is customized control in the unbound mode. datagridview.FirstDisplayedScrollingRowIndex is not set in a specific datagridview based event.
Rows are added to the datagridview via gatagridview.Rows.Add method on DataSet.EndMerge then cells are styled and formatted row by row. Last selected row is cleared and restored and scroll bar position restored to the first visible row.
Trying find out what this exception actually means.
if (gridView.Rows.Count > 0)
{
gridView.ClearSelection();
T value = GetItemByRow(gridView.Rows[0]);
bool isVisible = filter.ShouldShow(value);
gridView.Rows[0].Selected = true;
if (!isVisible)
{
gridView.Rows[0].Visible = true;
gridView.FirstDisplayedScrollingRowIndex = gridView.SelectedRows[0].Index;
gridView.Rows[0].Visible = false;
}
else
{
gridView.FirstDisplayedScrollingRowIndex = gridView.SelectedRows[0].Index;
}
}
When the grid is automatically sized to be 0 height (or probably width) and you set
dataGridView.FirstDisplayedScrollingRowIndex = 0;
the exception will be thrown. Our grid has set Dock = Fill and in some cases was sized to be invisible.
Our fix was to set a MinimumSize to 100/50, and we never saw the exception again. Even if the grid is not within the window (and thus invisible) the exception will now not be thrown.
When are row is present in the grid but not visible setting it to be first row will make it throw this exception.

Column Styles not working on TableLayoutPanel

I have a TableLayoutPanel that has a dynamic amount of columns and rows determined by the user. I want the buttons inside to be square and the same size, but whenever I use a loop to set the column/rows styles, they never turn out to be the size I want them to be.
How can I get the column/row styles to set the appropriate widths and height os the container elements?
Here is the loop method of the code that handles setting the width size of the table (I use a similar method for rows)
void FormatTableWidth(ref TableLayoutPanel container)
{
TableLayoutColumnStyleCollection columnStyles = container.ColumnStyles;
foreach (ColumnStyle style in columnStyles)
{
style.SizeType = SizeType.Absolute;
style.Width = 60;
}
}
You can do it like....
public void AddButtontControls()
{
tblPanel.SuspendLayout();
tblPanel.Controls.Clear();
tblPanel.GrowStyle = TableLayoutPanelGrowStyle.FixedSize;//.AddColumns;
tblPanel.ColumnStyles.Clear();
for (int i = 0; i < tblPanel.ColumnCount; i++)
{
ColumnStyle cs = new ColumnStyle(SizeType.Percent, 100 / tblPanel.ColumnCount);
tblPanel.ColumnStyles.Add(cs);
//Add Button
Button a = new Button();
a.Text = "Button " + i + 1;
tblPanel.Controls.Add(a);
}
tblPanel.ResumeLayout();
}
Sorry to tell you, but you don't use the right control.
You definitely must use FlowLayoutPanel control, and you can add as many controls you want in it, you can tell which direction will fill the control, if it wrap content or not, and many others.
And the most important - It Will Not Flickering like TableLayoutPanel does :)

DataGridView column auto adjust width and resizable

I am wondering if it is possible to have a dataGridView column to adjust automatically its width to its content and at the same time being resizable by the user ?
Here what i have tried so far :
dataGridView.AllowUserToResizeColumns = true;
dataGridView.Columns[0].AutoSizeMode=DataGridViewAutoSizeColumnMode.DisplayedCells;
dataGridView.Columns[0].Resizable = DataGridViewTriState.True;
But, I am still unable to resize the column size manually.
If anyone already faced this issue or have any idea let me know.
Thanks.
I finally find a way to do what I wanted.
The idea is to
let the dataGridView resize the columns itself to fit the content, and then
change theAutoSizeColumnMode and set the width with the value you just stored.
Here is the code:
dataGridView.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
int widthCol = dataGridView.Columns[i].Width;
dataGridView.Columns[i].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
dataGridView.Columns[i].Width = widthCol;
Hope this will help.
Building on the code above to iterate it for all columns and also auto adjust the width of the DataGridView
//initiate a counter
int totalWidth = 0;
//Auto Resize the columns to fit the data
foreach (DataGridViewColumn column in mydataGridView.Columns)
{
mydataGridView.Columns[column.Index].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
int widthCol = mydataGridView.Columns[column.Index].Width;
mydataGridView.Columns[column.Index].AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
mydataGridView.Columns[column.Index].Width = widthCol;
totalWidth = totalWidth + widthCol;
}
//the selector on the left of the DataGridView is about 45 in width
mydataGridView.Width = totalWidth + 45;
You can just use this simple code:
dataGridView1.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.DisplayedCells);
After setting datasource. It will set the width and allow resize.
The thing that is not obvious (it was not to me) is that use of AutoSizeMode means we want the size to be managed, so that implies that the user would not (cannot) do a resize. So what I have tried and it seems to work is to use DataGridView.AutoResizeColumn (note that it does a one-time resize) for each column or most columns then set DataGridView.AllowUserToResizeColumns to true. There are probably other variations but the important thing is that use of AutoSizeMode is mutually exclusive with allowing the user to do a resize.
Thanks for the solution above (To iterate through the DataGridView.Columns, change AutoSizeMode to a valid one, collect width value and set it back after change AutoSizeMode to DataGridViewAutoSizeColumnMode.None).
I struggled with it, and noticed it won't work whenever it is called from the class constructor or any line before Form.Show() or Form.ShowDialog(). So I put this code snippet in the Form.Shown event and this works for me.
My transformed code, reguardless of whatever DataGridView.AutoSizeColumnsMode set before, I use DataGridViewColumn.GetPreferredWidth() instead of changing DataGridViewColumn.AutoSizeMode and set the width value immediately, then change DataGridView.AutoSizeColumnsMode once:
private void form_Shown(object sender, EventArgs e)
{
foreach (DataGridViewColumn c in dataGridView.Columns)
c.Width = c.GetPreferredWidth(DataGridViewAutoSizeColumnMode.DisplayedCells, true);
dataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.None;
}
Be sure to set
dataGridView.AllowUserToResizeColumns = true;
I don't know how come this only works after the form is shown.
Simple solution: Either bound filed or template filed. you can use ItemStyle-Width
<asp:BoundField DataField="SSSS" HeaderText="XXX" ItemStyle-Width="125px"/>
<asp:TemplateField HeaderText="EEEE" ItemStyle-Width="100px">

Categories

Resources