hi there,

how can i assign a calender control to datagrid view cell by C# code.(like assigning values to a combobox in C# codeas below)

DataGridViewComboBoxColumn combobox = (DataGridViewComboBoxColumn)dgvActions.Rows[r].Cells[3].OwningColumn;
                            combobox.Items.Clear();
                            combobox.Items.AddRange(u.LoadUSEmp());

thankxxx

Comments
Good question

I found this that shows how to do it but its a bit complicated.
How to: Host Controls in Windows Forms DataGridView Cells

hey this is the one i have in my code but when i try to change the value in it it gies an error from ctl.Value = (DateTime)this.Value; line.
(i actually load the datato the datagrid view, and when i try to change the value in the datagridview calendercolumn cell it triggers this error)

how can i solve it
thnaxxxxxxx

I have tested the code for calendercolumn and it works fine if the DB column type is DateTime.
The issue must be that the column in your DB is a string (nvarchar or other text format).
Suitable changes to the calendercolumn code (e.g. using DateTime.ParseExact() as finito suggests) will get rid of the problems.
Try to understand :-/ the code and determine where you think the changes should be.
Post your changes and I'll help you correct any mistakes.:)

Edited 6 Years Ago by nick.crane: spelling corrections

Is your column in the DB a datetime or a nvarchar?

it is datetime

but the thing is when the value is retrieved from the database it comes as 7/12/2010 12.00.00AM. from this i get the date only and display in the datagrid view calender column cell

the code is below

DueDateTime = dt.Rows[r]["PDuedate"].ToString();
                    IndexSpace = DueDateTime.IndexOf(" ");
                    String DueDate = DueDateTime.Substring(0, IndexSpace);

                    dgvActions.Rows[r].Cells[4].Value = DueDate;

thankxxx

Are you not using dgvAction.DataSource to populate your data grid directly from your data table (e.g. dgvAction.DataSource = dt; )?

Also, if you did not convert the value to string the type would remain as a datetime and the calendar column might work as it is. e.g.

dgvActions.Rows[r].Cells[4].Value = dt.Rows[r]["PDuedate"].Value;

Or to get just the date part

dgvActions.Rows[r].Cells[4].Value = ((DateTime)dt.Rows[r]["PDuedate"].Value).Date;

Edited 6 Years Ago by nick.crane: n/a

Are you not using dgvAction.DataSource to populate your data grid directly from your data table (e.g. dgvAction.DataSource = dt; )?

Also, if you did not convert the value to string the type would remain as a datetime and the calendar column might work as it is. e.g.

dgvActions.Rows[r].Cells[4].Value = dt.Rows[r]["PDuedate"].Value;

Or to get just the date part

dgvActions.Rows[r].Cells[4].Value = ((DateTime)dt.Rows[r]["PDuedate"].Value).Date;

the code i below(the way i populate the datagrid view)

public void DActionDetails(String ID,int Phase)
        {
            String DueDateTime = "";
            int IndexSpace = 0;

            String query = @"Select PActionID,PDes,PAssignTo,PDuedate,PStatus,PComDate From PAction Where ID=@id and Phase=@phase";
            SqlCommand command = new SqlCommand(query,DB.getConnection());

            command.Parameters.Add("@id",SqlDbType.VarChar).Value = ID;
            command.Parameters.Add("@phase",SqlDbType.Int).Value = Phase;

            db.openConnection();
            SqlDataAdapter da = new SqlDataAdapter(command);
            DataTable dt = new DataTable();

            da.Fill(dt);
            dgvACount = dt.Rows.Count;
                   
            if (dgvACount == 0)
            {
            }
            else
            {
                dgvActions.Rows.Add(dgvACount);

                

                for (int r = 0; r < dt.Rows.Count; r++)
                {
                    dgvActions.Rows[r].Cells[1].Value = dt.Rows[r]["PActionID"].ToString();
                    dgvActions.Rows[r].Cells[2].Value = dt.Rows[r]["PDes"].ToString();
                    dgvActions.Rows[r].Cells[3].Value = dt.Rows[r]["PAssignTo"].ToString();

                    [B]DueDateTime = dt.Rows[r]["PDuedate"].ToString();
                    IndexSpace = DueDateTime.IndexOf(" ");
                    String DueDate = DueDateTime.Substring(0, IndexSpace);

                    dgvActions.Rows[r].Cells[4].Value = DueDate;[/B]

                    dgvActions.Rows[r].Cells[5].Value = dt.Rows[r]["PStatus"].ToString();
                    dgvActions.Rows[r].Cells[6].Value = dt.Rows[r]["PComDate"].ToString();
                }
            }
            db.closeConnection();      

        }

the bold text is the place i was talking about

thanxxxxxxxxx

Try this.
It will likely have quite a few consequences with all your validation and column header etc. but try it to see what happens.
(At this stage of your coding I do not recommend that you change. Just do it to see what happens. Unless you really want to of course.)

public void DActionDetails(String ID, int Phase)
        {
            String DueDateTime = "";
            int IndexSpace = 0;

            String query = @"Select PActionID,PDes,PAssignTo,PDuedate,PStatus,PComDate From PAction Where ID=@id and Phase=@phase";
            SqlCommand command = new SqlCommand(query, DB.getConnection());

            command.Parameters.Add("@id", SqlDbType.VarChar).Value = ID;
            command.Parameters.Add("@phase", SqlDbType.Int).Value = Phase;

            db.openConnection();
            SqlDataAdapter da = new SqlDataAdapter(command);
            DataTable dt = new DataTable();

            da.Fill(dt);
            dgvACount = dt.Rows.Count;

            dgvActions.DataSource = dt; //<--- pupulate the data grid with data from table

            //if (dgvACount != 0)   // <--- test for none zero row count
            //{
            //    dgvActions.Rows.Add(dgvACount);
            //    for (int r = 0; r < dt.Rows.Count; r++)
            //    {
            //        dgvActions.Rows[r].Cells[1].Value = dt.Rows[r]["PActionID"].ToString();
            //        dgvActions.Rows[r].Cells[2].Value = dt.Rows[r]["PDes"].ToString();
            //        dgvActions.Rows[r].Cells[3].Value = dt.Rows[r]["PAssignTo"].ToString();

            //        DueDateTime = dt.Rows[r]["PDuedate"].ToString();
            //        IndexSpace = DueDateTime.IndexOf(" ");
            //        String DueDate = DueDateTime.Substring(0, IndexSpace);

            //        dgvActions.Rows[r].Cells[4].Value = DueDate;

            //        dgvActions.Rows[r].Cells[5].Value = dt.Rows[r]["PStatus"].ToString();
            //        dgvActions.Rows[r].Cells[6].Value = dt.Rows[r]["PComDate"].ToString();
            //    }
            //}

            db.closeConnection();

        }

Edited 6 Years Ago by nick.crane: n/a

Try this.
It will likely have quite a few consequences with all your validation and column header etc. but try it to see what happens.
(At this stage of your coding I do not recommend that you change. Just do it to see what happens. Unless you really want to of course.)

public void DActionDetails(String ID, int Phase)
        {
            String DueDateTime = "";
            int IndexSpace = 0;

            String query = @"Select PActionID,PDes,PAssignTo,PDuedate,PStatus,PComDate From PAction Where ID=@id and Phase=@phase";
            SqlCommand command = new SqlCommand(query, DB.getConnection());

            command.Parameters.Add("@id", SqlDbType.VarChar).Value = ID;
            command.Parameters.Add("@phase", SqlDbType.Int).Value = Phase;

            db.openConnection();
            SqlDataAdapter da = new SqlDataAdapter(command);
            DataTable dt = new DataTable();

            da.Fill(dt);
            dgvACount = dt.Rows.Count;

            dgvActions.DataSource = dt; //<--- pupulate the data grid with data from table

            //if (dgvACount != 0)   // <--- test for none zero row count
            //{
            //    dgvActions.Rows.Add(dgvACount);
            //    for (int r = 0; r < dt.Rows.Count; r++)
            //    {
            //        dgvActions.Rows[r].Cells[1].Value = dt.Rows[r]["PActionID"].ToString();
            //        dgvActions.Rows[r].Cells[2].Value = dt.Rows[r]["PDes"].ToString();
            //        dgvActions.Rows[r].Cells[3].Value = dt.Rows[r]["PAssignTo"].ToString();

            //        DueDateTime = dt.Rows[r]["PDuedate"].ToString();
            //        IndexSpace = DueDateTime.IndexOf(" ");
            //        String DueDate = DueDateTime.Substring(0, IndexSpace);

            //        dgvActions.Rows[r].Cells[4].Value = DueDate;

            //        dgvActions.Rows[r].Cells[5].Value = dt.Rows[r]["PStatus"].ToString();
            //        dgvActions.Rows[r].Cells[6].Value = dt.Rows[r]["PComDate"].ToString();
            //    }
            //}

            db.closeConnection();

        }

hey if i do it this way how can i add the calender column to the datagrid view???

add also i have add the datagrid view columns from the interface, how do i load data to this.

thankxx

I did say you might not want to change your code. However, it should be possible to do.
Try setting the DataPropertyName property of the columns you have already configured, before setting the DataSource property.
Not really sure if this will work cos I generally connect to the db in design studio and work with a strongly typed dataset.

Edited 6 Years Ago by nick.crane: n/a

I did say you might not want to change your code. However, it should be possible to do.
Try setting the DataPropertyName property of the columns you have already configured, before setting the DataSource property.
Not really sure if this will work cos I generally connect to the db in design studio and work with a strongly typed dataset.

hi thankx for the support

by the way how can it do this "Try setting the DataPropertyName property of the columns you have already configured, before setting the DataSource property."

which u have mentioned??

thankx

hi thankx for the support

by the way how can it do this "Try setting the DataPropertyName property of the columns you have already configured, before setting the DataSource property."

which u have mentioned??

thankx

E.G.

YourPActionIDColumn.DataPropertyName = "PActionID";
YourPDesColumn.DataPropertyName = "PDes";
YourPAssignToColumn.DataPropertyName = "PAssignTo";
...
dgvActions.DataSource = dt; //<--- pupulate the data grid with data from table

Judith,
How did you get on with this?
Did you go back to using the for loop to fill you DGV?
Do you still have a problem with the DateTime column?

Judith,
How did you get on with this?
Did you go back to using the for loop to fill you DGV?
Do you still have a problem with the DateTime column?

hey i need the loop to be there, because there is another code in relatin to that so by keeping the loop how can i do this,
thanxxx

the code i below(the way i populate the datagrid view)

public void DActionDetails(String ID,int Phase)
        {
            String DueDateTime = "";
            int IndexSpace = 0;

            String query = @"Select PActionID,PDes,PAssignTo,PDuedate,PStatus,PComDate From PAction Where ID=@id and Phase=@phase";
            SqlCommand command = new SqlCommand(query,DB.getConnection());

            command.Parameters.Add("@id",SqlDbType.VarChar).Value = ID;
            command.Parameters.Add("@phase",SqlDbType.Int).Value = Phase;

            db.openConnection();
            SqlDataAdapter da = new SqlDataAdapter(command);
            DataTable dt = new DataTable();

            da.Fill(dt);
            dgvACount = dt.Rows.Count;
                   
            if (dgvACount == 0)
            {
            }
            else
            {
                dgvActions.Rows.Add(dgvACount);

                

                for (int r = 0; r < dt.Rows.Count; r++)
                {
                    dgvActions.Rows[r].Cells[1].Value = dt.Rows[r]["PActionID"].ToString();
                    dgvActions.Rows[r].Cells[2].Value = dt.Rows[r]["PDes"].ToString();
                    dgvActions.Rows[r].Cells[3].Value = dt.Rows[r]["PAssignTo"].ToString();

                    [B]DueDateTime = dt.Rows[r]["PDuedate"].ToString();
                    IndexSpace = DueDateTime.IndexOf(" ");
                    String DueDate = DueDateTime.Substring(0, IndexSpace);

                    dgvActions.Rows[r].Cells[4].Value = DueDate;[/B]

                    dgvActions.Rows[r].Cells[5].Value = dt.Rows[r]["PStatus"].ToString();
                    dgvActions.Rows[r].Cells[6].Value = dt.Rows[r]["PComDate"].ToString();
                }
            }
            db.closeConnection();      

        }

the bold text is the place i was talking about

thanxxxxxxxxx

Assuming that the PDuedate column is a DateTime type.
Try this in place of the bold part from your above post.

DateTime DueDate = dt.Rows[r]["PDuedate"];
dgvActions.Rows[r].Cells[4].Value = DueDate.Date;

This passes in a DateTime type to the DGV cell instead of a string type.
Remember to set that column to a CalendarColumn too.

Assuming that the PDuedate column is a DateTime type.
Try this in place of the bold part from your above post.

DateTime DueDate = dt.Rows[r]["PDuedate"];
dgvActions.Rows[r].Cells[4].Value = DueDate.Date;

This passes in a DateTime type to the DGV cell instead of a string type.
Remember to set that column to a CalendarColumn too.

oohh yeah this was the thing i wanted
thanxxxxxx

Are you not using dgvAction.DataSource to populate your data grid directly from your data table (e.g. dgvAction.DataSource = dt; )?

Also, if you did not convert the value to string the type would remain as a datetime and the calendar column might work as it is. e.g.

dgvActions.Rows[r].Cells[4].Value = dt.Rows[r]["PDuedate"].Value;

Or to get just the date part

dgvActions.Rows[r].Cells[4].Value = ((DateTime)dt.Rows[r]["PDuedate"].Value).Date;

hey what if the database has no value for the calender column in the datagrid view how can i handle it.

when i put the code
if ((DueDate.CompareTo("1/1/1900 12:00:00 AM") == 0) || (string.IsNullOrEmpty(DueDate)))
dgvActions.Rows[r].Cells[4].Value = "";
and click on the cell it gives the error as the the ones which is mentioned in the beginning

thanxxxxx

You need to switch around your conditions. You should check if the variable is null, only if it is not null should you try to compare its value.

You need to switch around your conditions. You should check if the variable is null, only if it is not null should you try to compare its value.

hey i wrote the code like this

string ComDate = dt.Rows[r]["ComDate"].ToString();
                    if ((ComDate.Equals("1/1/1900 12:00:00 AM")) || (string.IsNullOrEmpty(ComDate)))
                        dgvFrom.Rows[r].Cells[6].Value = null;
                    else
                    {
                        int spaceIndex = ComDate.LastIndexOf(" ");
                        string date = ComDate.Substring(0,spaceIndex);
                        DateTime comDate = DateTime.Parse(date);
                        dgvFrom.Rows[r].Cells[6].Value = comDate.Date;
                    }

thanxxx

You still havent switched the conditions.
As a general rule of thumb, you should perform the "is null" check before you do the "is equal to" check:

if ((string.IsNullOrEmpty(ComDate)) || (ComDate.Equals("1/1/1900 12:00:00 AM")))

The || is the symbol for an XOR operation. XOR is an exlusive test, which means if the first part equates to "true" then the second part is not processed. Using an exlusive test in this way ensures that if the object is null you dont ever try to compare its value and thus throw a null value exception.

This article has been dead for over six months. Start a new discussion instead.