How to make format mask in DataGridView cell?

9.2k views Asked by At

I need to make a format/mask in a cell that prevents the user from entering data that isn't relevant.

The column cell contains date values like "MM/YYYY" without a day value.

I tried the following to make this definition but without success:

dataGridView1.Columns[0].DefaultCellStyle.Format = "##/####" // || dd/yyyy

Also, I tried to go to the properties of DataGridView and define Format from there.

1

There are 1 answers

0
OhBeWise On

The method you're using for formatting is a valid approach. There are a few issues that may be happening here. Please ensure:

  1. The underlying data is of type DateTime and not type string. Type string will not apply the format as expected. (See columns 1 and 2 in example below.)
  2. The individual DataGridViewTextBoxCell.Style.Format isn't being set to something different than your desired format. This would override the column formatting. (See column 3 in example below.)

EXAMPLE

this.dataGridView1.ColumnCount = 4;
this.dataGridView1.RowCount = 1;
this.dataGridView1.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;

DateTime date = DateTime.Now;

this.dataGridView1[0, 0].Value = date;
this.dataGridView1[1, 0].Value = date.ToString();
this.dataGridView1[2, 0].Value = date.ToString("MM/yyyy");
this.dataGridView1[3, 0].Value = date;

this.dataGridView1[3, 0].Style.Format = "MM/yyyy";

this.dataGridView1.Columns[0].DefaultCellStyle.Format = "dd/yyyy";
this.dataGridView1.Columns[1].DefaultCellStyle.Format = "dd/yyyy";
this.dataGridView1.Columns[2].DefaultCellStyle.Format = "dd/yyyy";
this.dataGridView1.Columns[3].DefaultCellStyle.Format = "dd/yyyy";

Cols output: 16/2016, 12/16/2016 8:52:17 AM, 12/2016, 12/2016

As you can see from the output:

  1. Columns[0] contains a DateTime and correctly formats as "dd/yyyy".
  2. Columns[1] contains a string and cannot be reformatted to "dd/yyyy".
  3. Columns[2] contains a formatted string and cannot be reformatted to "dd/yyyy".
  4. Columns[3] contains a DateTime and formatting is overridden by the cell format "MM/yyyy".

To correct these issues, just set your cell value using the DateTime object and not any string representation.

In the case where you are getting this data from some outside source and it's already of type string, you can Parse it, but note that the missing portions of the DateTime object will be defaulted and there's really nothing you can do about that without having the original full data:

DateTime date = DateTime.Parse("10/2016");
Console.WriteLine("Output: {0}", date.ToString());

// Output: 10/1/2016 12:00:00 AM

Validation

If validating user input (and losing formatting on edits) is your main concern, consider the following method for validation to cancel an invalid edit:

private void DataGridView1_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
{
    DateTime parsed;
    if (!DateTime.TryParse(e.FormattedValue.ToString(), out parsed))
    {
        this.dataGridView1.CancelEdit();
    }
}

Coupled with this answer for reapplying your format using the DataGridView.CellFormatting event handler. (Note that this also negates the need to ensure your data types are not string, but is more costly due to the event being triggered often.)