views:

800

answers:

3

I have a DGV bound to a list of objects. This works fine except that one of the object properties is boolean and therefore displays as a checkbox but I would prefer a simple yes/no text field instead. I've considered adding an additional column and populating with the appropriate string based on the boolean value but this seems a little over the top. Is there an easier way?

The DGV is read-only.

A: 

Edit the column that displays the boolean so the ColumnType property = DataGridViewTextBoxColumn.

The column will now display the strings True/False.

Make this change in the designer:

  1. In the designer, right click the DGV.

  2. On the popup menu, select 'Edit Columns...' The Edit Columns dialog will appear.

  3. In the Edit Columns dialog, pick your column on the left and find the properties (including ColumnType) on the right.

You can set the ColumnType programmatically when a column is being added to your DGV:

DataGridViewColumn column = new DataGridViewColumn();
DataGridViewCell cell = new DataGridViewTextBoxCell();
column.CellTemplate = cell;
dgv.Columns.Add(column);

Code from MSDN.

Jay Riggs
I can't see a 'ColumnType' property: Me.DGV.Columns("ColName").?
Simon
I clarified a bit on how to do this!
Jay Riggs
Good idea but I need to do this programatically as the DGV is built dynamically at runtime.
Simon
Found this on MSDN: "The ColumnType property is a design-time-only property that indicates the class representing the column type. It is not an actual property defined in a column class." Square 1!
Simon
Oh sorry. Let me look into this a bit...
Jay Riggs
There's a way to do this if you're still interested.
Jay Riggs
A: 

It looks like this is not possible so I cheated. I added a read-only property to my business object which returns a string based on the boolean property. I just hid the boolean column in the DGV and displayed the string property.

Simon
True, but you can set the ColumnType when you create the column before you add it your DataGridView.
Jay Riggs
+1  A: 

As mentioned above it seems to be impossible to change the visual appearance of boolean values in a data bound scenario. Even DataGridViewCellStyle.FormatProvider does not work correctly with types like System.Int32, System.Int64, System.Decima, etc.

Therefore I found a workaround which works for me. Probably it is not the best solution but currently it fits my needs. I handle the DataGridView.ColumnAdded event and replace DataGridViewCheckBoxColumn with DataGridViewTextBoxColumn. Afterwards I use CellFormating event (recommended by Microsoft, see links above) to format source data.

private DataGridViewTextBoxColumn textBoxColumn = null;
void _dataGrid_ColumnAdded(object sender, DataGridViewColumnEventArgs e)
{
    // Avoid recursion
    if (e.Column == textBoxColumn) return;

    DataGridView gridView = sender as DataGridView;
    if (gridView == null) return;

    if( e.Column is DataGridViewCheckBoxColumn)
    {
        textBoxColumn = new DataGridViewTextBoxColumn();
        textBoxColumn.Name = e.Column.Name;
        textBoxColumn.HeaderText = e.Column.HeaderText;
        textBoxColumn.DataPropertyName = e.Column.DataPropertyName;

        gridView.Columns.Insert(e.Column.Index, textBoxColumn);
        gridView.Columns.Remove(e.Column);
    }
}

void _dataGrid_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
{
    DataGridViewColumn col = _dataGrid.Columns[e.ColumnIndex];

    try
    {
        if ( col.Name == "IsMale")
        {
            bool isMale = Convert.ToBoolean(e.Value);
            e.Value = isMale ? "male" : "female";
        }
    }
    catch (Exception ex)
    {
        e.Value = "Unknown";
    }
}
Alex