简体   繁体   中英

DataGridView display row header cell

I'm trying to display a simple DataGridView linked to a DataTable and I want, ultimately, my first column in the DataTable to be the row header cell for the DataGridView. At this point I will settle for having any value in the row header cell. I can display the DataGridView with all my rows and columns, and with column header cells, but no row header cell. I check the value in the row.HeaderCell.Value, and the data I put there is there. I check row.HeaderCell.Displayed and it is false, but this is read only, so I can't make it true. How do I make the row header cell display?

Here's a simple sample of what I've tried to get this to work:

        DataTable table = new DataTable();
        for (int i = 0; i<10; i++)
        {
            table.Columns.Add(new DataColumn("column-" + i));
        }

        for (int i = 0; i < 10; i++)
        {
            DataRow theRow = table.NewRow();

            for (int j = 0; j < 10; j++)
                theRow[j] = i + "-" + j;
            table.Rows.Add(theRow);

        }

        dataGridView1.DataSource = table;
        dataGridView1.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
        int rowNumber = 1;
        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            if (row.IsNewRow) continue;
            row.HeaderCell.Value = "Row " + rowNumber;
            rowNumber = rowNumber + 1;
        }
        dataGridView1.AutoResizeRowHeadersWidth(
            DataGridViewRowHeadersWidthSizeMode.AutoSizeToAllHeaders);

If you place this code in the constructor, it will not work. Move the code into the form's Load event and it should work fine. A common problem with Windows.Forms and C# is the use of improper initialization in the constructor. Many controls are not fully created until after the constructor finishes. (I forget why, but I believe it is because the handle is not created yet.) Many "work arounds" can be avoided, if you initialize in the Load event as recommended by Microsoft.

只需调用ToString(),如下所示

 row.HeaderCell.Value = ("Row " + rowNumber).ToString();

The answer appears to be handling the DataGridView.CellFormatting event. Why setting the value elsewhere doesn't work is beyond me, but I'm sure there's a reason. I added the following event handler and all is good:

    private void dataGridView_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
    {
        DataGridView gridView = sender as DataGridView;

        if (null != gridView)
        {

            gridView.Rows[e.RowIndex].HeaderCell.Value = gridView.Rows[e.RowIndex].Cells[0].Value;
            Console.WriteLine("GridViewCell: " + gridView.Rows[e.RowIndex].Cells[0].Value);

        }
    }

I used Karl's answer, but changed the event handler to RowsAdded, assuming the row header name is not changing once the row is created. The issue with CellFormatting is that it is called for every column, so it wastes some time setting the HeaderCell.Value over and over again.

    private void dataGridViewVersions_RowsAdded(object sender, DataGridViewRowsAddedEventArgs e)
    {
        DataGridView gridView = sender as DataGridView;
        MyData vr = gridView.Rows[e.RowIndex].DataBoundItem as MyData ;
        if (vr != null)
        {
            gridView.Rows[e.RowIndex].HeaderCell.Value = vr.RowName.ToString();
        }
    }

After assigning values to the datagridview, either by binding or manually, i did the following:

foreach (DataGridViewRow row in dgvValues.Rows)
{
     row.HeaderCell.Value = (row.Index+1).ToString();
}

and it worked for me. I think there should be some even simpler workaround in Linq.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM