views:

352

answers:

3

I have a list that I have bound to a datagridview. I want the first column to be a fixed size. The data is bound to the dataGridView and I can't seem to find a way to access an individual colums properties. if I try myDatagridview.colums[0] I get an index out of bounds, since it says the columns count is 0.

   private DataGridView setUpDataGrid(List<NVRlineVal> _NVRData)
    {
        //setup dataGridView
        DataGridView NVRDataGridView = new System.Windows.Forms.DataGridView();
        NVRDataGridView.ColumnHeadersHeightSizeMode =
            System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        NVRDataGridView.Dock = System.Windows.Forms.DockStyle.Fill;
        NVRDataGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;


        NVRDataGridView.Name = "NVRDataGridView" + nvrIndex;
        NVRDataGridView.RowHeadersWidthSizeMode =
            System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
        NVRDataGridView.TabIndex = 0;
        NVRDataGridView.DataSource = _NVRData;
        //var clmn = NVRDataGridView.Columns[0];

        return NVRDataGridView;
    }

Any ideas on how to have a fixed column width for only one of these columns, the rest will autosize?

edited original code, to show a more cleaned up version that still works

+1  A: 
myDatagridview.colums[0] 

this should fine as long as you use it AFTER you bind the data. when I do thing like this I set the width of the columns after I finished all the code regarding the data.

I prefer not to use the autosize in neither Headers.

Luiscencio
Doesn't work for me even when I use it after the line:NVRDataGridView.DataSource = _NVRData;
Andy
try it without the `NVRDataGridView.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;` line
Luiscencio
after I took out the line you mentioned, I tried this a after the data binding and I get an out of range exception: var clmn = NVRDataGridView.Columns[0];
Andy
weird... let me run your code
Luiscencio
I guess you were right, but I thought setting the datasource bound the data, but that actually occurs later on. So I just setup an eventhandler like Paul mentioned and took care of it in there.
Andy
A: 

Using your code i found something that works.

I seperated the column size change from the creation thread which i suspect is called at the form's constructor.

Instead, i placed it in the VisibleChanged event of the form.

It works for me. note that for this you will have to place the declaration:

DataGridView NVRDataGridView

at the form level for other methods to access, but you can leave the initialisation in the update method.

private void Form1_VisibleChanged(object sender, EventArgs e)
        {
            if (this.Visible)
            {
                this.Invoke(new EventHandler(delegate
                {
                    if (NVRDataGridView.ColumnCount > 0)
                    {
                        NVRDataGridView.Columns[0].Width = 20;
                    }
                }));
            }
        }
Lily
THanks, I'm on the way out the door, but will try it first thing in the morning. Will report back with results
Andy
+1  A: 

I do something similar but with formatting.

The problem is that the grid is not drawn after the setting of the data source - you need to do you changes in the DataBindingComplete event.

Here are some snippets....

(from https://minisqlquery.svn.codeplex.com/svn/trunk/MiniSqlQuery/QueryForm.cs)

-- grid def:

        this.gridResults1.AllowUserToAddRows = false;
        this.gridResults1.AllowUserToDeleteRows = false;
        this.gridResults1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.ColumnHeader;
        this.gridResults1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
        this.gridResults1.Dock = System.Windows.Forms.DockStyle.Fill;
        this.gridResults1.Location = new System.Drawing.Point(3, 3);
        this.gridResults1.Name = "gridResults1";
        this.gridResults1.ReadOnly = true;
        this.gridResults1.Size = new System.Drawing.Size(1023, 242);
        this.gridResults1.TabIndex = 0;

-- later on subscribe to DataBindingComplete event:

grid.DataBindingComplete += GridDataBindingComplete;

-- handle the event (here I am modifying the format but you try changing the width):

    private void GridDataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
    {
        DataGridView grid = sender as DataGridView;
        if (grid == null)
        {
            return;
        }
        DataTable dt = grid.DataSource as DataTable;
        if (dt == null)
        {
            return;
        }

        string nullText = _settings.NullText;
        string dateTimeFormat = _settings.DateTimeFormat;

        for (int i = 0; i < dt.Columns.Count; i++)
        {
            if (dt.Columns[i].DataType == typeof (DateTime))
            {
                DataGridViewCellStyle dateCellStyle = new DataGridViewCellStyle();
                dateCellStyle.NullValue = nullText;
                dateCellStyle.Format = dateTimeFormat;
                grid.Columns[i].DefaultCellStyle = dateCellStyle;
            }
        }
    }
Paul Kohler
Thanks, I just added my stuff to the event handler after the binding and it worked.
Andy
Sweet! I actually need to add a similar tweak so that columns that are auto-sized don't get too big, thanks for reminding me!! PK :-)
Paul Kohler