tags:

views:

438

answers:

3

I'm trying to manually draw cells in a DataGridView. Specifically I'd like to draw a row of CheckBoxes. Normally you can add a DataGridViewCheckBoxColumn, but as far as I'm aware, there isn't a DataGridViewCheckBoxRow. (I can't just create lots of DGVCheckBoxColumns because I'd like different cell types in different rows).

I've overridden the DGV's OnCellPainting() method. I've created a DGVCheckBoxCell:

protected override void OnCellPainting(DataGridViewCellPaintingEventArgs e)
{
   DataGridViewCheckBoxCell cbcell = new DataGridViewCheckBoxCell();
}

I'm not sure what to do next.


More info:

I'm ultimately trying to transpose a datagridview. So I might have a CheckBoxColumn, a ComboBoxColumn, a TextBoxColumn, and any other type of column, then turn them into rows. I don't think I can make DGVRows, so I think I'm going to have to deal with indiviual cells.

Thanks for all the answers so far...

+1  A: 

As far as I can see, you have two options:

  1. Create a special Cell type derived from DataGridViewCell that behaves differently depending on the contents of that cell. You can then set that Cell type as the CellTemplate of each column, and the DataGridView will automatically construct instances of it to use. Painful, but relatively easy to understand and not too hard to do - just tedious.

  2. The same as #1, but instead of making a wacky Cell type, create a special CellTemplate and override its Clone method. Have the Clone method automatically determine the correct type of cell to construct and return that, instead of returning a raw clone of the template. This is a terrible hack and I don't recommend it unless you can't get the first approach to work.

Using the second approach successfully will require having knowledge of the row currently being constructed (if you look at DataGridViewRow.CreateCells in Reflector, you can get an idea of how it works). Knowing which type to construct will require having knowledge of the current row, and I'm not 100% certain you can get that. But I suspect it's possible if you're willing to give it a shot and dig around.

Kevin Gadd
I like the sound of the first option - could you point me in the direction of more info? Or give more details?
Tim Gradwell
Certainly. I haven't ever had to solve this problem before, but the basic approach should be simple (albeit time-consuming):What you're going to want to do is derive from DataGridViewCell, and override all the virtual/abstract members it exposes. Then, forward all of those method calls directly to the underlying cell type.Once you have that working, you can extend your custom type to select and construct the proper cell type at runtime when it's first used, or on the fly in order to change cell types dynamically.
Kevin Gadd
+2  A: 

The only thing I can think of would be to paint the checkbox yourself, which can be done but is a PIA. Because once you do that, you then have to control all the painting for hovering/checking/unchecking etc... However, here's some code to get you started:

void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
        {
            e.Paint(e.ClipBounds, DataGridViewPaintParts.All);
            if (e.RowIndex == 2) //I chose a random number, but this is the row you want with checkboxes
            {

                var rect = this.dataGridView1.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true);
                //The CheckBoxState enum has all different values for different "visual states"
                CheckBoxRenderer.DrawCheckBox(e.Graphics, new Point(rect.X, rect.Y), System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal);
                e.Handled = true;
            }
        }

Good luck!!

BFree
A: 

Here someone asked the same: http://www.vbforums.com/showthread.php?p=3352360 "You need to create new DataGridViewTextBoxCell objects and assign them to the items of the row's Cells collection." I have not figured yet out how to do that.

On http://weblogs.asp.net/kdente/archive/2005/02/20/377119.aspx he writes that it is possible.

Is your scenario databound?

Christian