Search code examples
c#datagridviewdatagridviewtextboxcell

Host Checkbox in a DataGridViewTextBoxCell


I have a custom DataGridView with a number of different Cell Types which inherit from DataGridViewTextBoxCell and DataGridViewCheckBoxCell.

Each of these custom cells has a property for setting a background Colour (needed for some functionality of the grid) called CellColour.

For simplicity we'll take two of the custom cells:

public class FormGridTextBoxCell : DataGridViewTextBoxCell
{
     public Color CellColour { get; set; }
     ...
}

public class FormGridCheckBoxCell : DataGridViewCheckBoxCell
{
     public Color CellColour { get; set; }
     ...
}

PROBLEM:

This means that every time I want to set the CellColour property for a Grid Row which contains columns of both Type FormGridTextBoxColumn and FormGridCheckBoxColumn (which have CellTemplaes of the aforementioned custom Cell Types respectively) I have to do the following:

if(CellToChange is FormGridTextBoxCell)
{
     ((FormGridTextBoxCell)CellToChange).CellColour = Color.Red;
}
else if (CellToChange is FormGridCheckBoxCell)
{
     ((FormGridCheckBoxCell)CellToChange).CellColour = Color.Red;
}

When you have 3+ different Cell Types, this is becoming arduous and I am convinced there is a better way of doing this.

SOLUTION SOUGHT:

I have it in my head that if I can create a single class which inherits from DataGridViewTextBoxCell and then have the custom Cell Types in turn inherit from this class:

public class FormGridCell : DataGridViewTextBoxCell
{
     public Color CellColour { get; set }
}

public class FormGridTextBoxCell : FormGridCell
{
     ...
}

public class FormGridCheckBoxCell : FormGridCell
{
     ...
}

I will then only need to do the following:

if(CellToChange is FormGridCell)
{
     ((FormGridCell)CellToChange).CellColour = Color.Red;
     ...
}

Regardless of how many custom Cell Types there are (as they will all inherit from FormGridCell); any specific control-driven cell types will implement Windows Forms Controls within them.

WHY THIS IS A PROBLEM:

I have tried following this article:

Host Controls in Windows Forms DataGridView Cells

This works for the custom DateTime picker however hosting a CheckBox in the DataGridViewTextBoxCell is a different kettle of fish as there are different properties to control the value of the cells.

If there is an easier way to start with a DataGridViewTextBoxCell and change the Data Type in inherited classes to a pre-defined Data Type more easily than this then I am open to suggestions however the core issue is hosting a checkbox within a DataGridViewTextBoxCell.


Solution

  • As I'm sure you've found, a single class may only inherit from one base class. What you are wanting is an interface, such as:

    public interface FormGridCell
    {
        Color CellColor { get; set; }
    }
    

    From there, you can create your sub-classes quite similarly, inheriting from their respective DataGridViewCell types as well as implementing the interface:

    public class FormGridTextBoxCell : DataGridViewTextBoxCell, FormGridCell
    {
        public Color CellColor { get; set; }
    }
    
    public class FormGridCheckBoxCell : DataGridViewCheckBoxCell, FormGridCell
    {
        public Color CellColor { get; set; }
    }
    

    At this point the usage is as simple as you'd hoped; create the cells via the CellTemplate, and as needed just cast cells to the interface type and you're free to do as you wanted (to see the results visually, I set the cell's BackColor as an example):

    if (cell is FormGridCell)
    {
        (cell as FormGridCell).CellColor = Color.Green;
        cell.Style.BackColor = Color.Green;
    }
    else
    {
        cell.Style.BackColor = Color.Red;
    }