Hi everyone,
Want a DateTimePicker column in my DataGridView.
Essentially used code I found on MSDN here
Just dropped the different classes in separate files.
It works, but the problem is I have to click from 2 to 4 times before I can select a date! The first click shows the DateTimePicker and then you have to click again to select a date.
Does anyone have any idea how I can let look all the cells in the column like the one in the bottom(see screenshot)?
Thanks in advance.

Recommended Answers

All 13 Replies

Hey Danny, I played around with the example MSDN code for a little while this morning, tweaking here and there, and I couldn't find an easy way to make the existing code produce the desired behavior. I think what you would need to do to is override the default behavior of the DataGridViewTextBoxCell in the definition of:

public class CalendarCell : DataGridViewTextBoxCell

or, perhaps implement a customized version of: DataGridViewComboBoxCell that incorporates the DateTimePicker implementation and inherit from that instead.

I hope that someone will provide a reasonable solution, because I feel this is something that can be achieved without much overhead and I would like to see the necessary changes because I haven't spent much time with DataGridView's and am curious too.

In the MFC days, we would draw a combobox button in the cell right-justified and then monitor for a click in that region and produce the behavior that it was a combobox, or in your case, a DateTimePicker. However, things are simpler now and I just know someone will have a better suggestion to deal with this.

Hey David,
Appreciate very much the time and effort you put into this:)
Already did some stuff myself but with the same effect.
Thanks.

What about if you made the datetime picker invoke the popup date selector on the first click of the cell instead of showing the editor glyph on all of the columns? I use a third party set of controls that provides the behavior you're describing -- but implemented the way I explained it.

IE if the row isn't selected and you click on another row, it will show the editor like the cell in the bottom row in your example (if you click the left 90% of the cell).

However if the row isn't selected and you click where the glyph *should be* then it will automagically invoke the date editor.

They're two different approaches and I think it looks a little better so you don't have the extra cludge of the control in your grid when the cell isn't focused, but you still have the 1-click ease of access.

Hi Scott, if I understand you well, I really don't need those glyphs. The column title is probably sufficient to tell me that I have to fill in a date. All I want is that from the first click I see a DateTimePicker popping up.

Here is a video of the functionality i'm describing. Notice how when I click on the left part of the control it creates the editor and shows the glyph. But if I click on another row where the glyph should be it automatically invokes the editor.

Maybe your code needs,

dataGridView1.EditMode = DataGridViewEditMode.EditOnEnter;

Thanks for the tip adatapost :)
It works, but only for the first cell of the column(I think the cell that has the focus) I will investigate this further.

I'll take a stab at it in the morning and see if I have any luck with it

Give this a shot.

[edit]
Oh make sure when you first open the project you close all of the open tabs, compile the project, then open the form. It needs to be built at least one time before the designer will work :)
[/edit]

The last one had a bug, I didn't check which mouse button was down. The right doesn't fire a row selection change the way I had it setup but it can. Try this one.

This also only fires off if they click on right 15 pixels which is the ~approximate width of the glyph, i'm not sure on how to get the exact width off hand so this is close enough I think :)

If you want to change it where it opens the DateTime picker when they click in the cell, not just on the glyph you can swap out the method below with this code:

public void PrepareEditingControlForEdit(bool selectAll)
    {
      if (dataGridView.EditingControl == this)
      {
        Rectangle rect = dataGridView.GetCellDisplayRectangle(dataGridView.CurrentCell.ColumnIndex, rowIndex, true);
        MouseInfo mi = new MouseInfo(Control.MouseButtons);
        Point mousePos = dataGridView.PointToClient(Control.MousePosition);
        //if (mi.LeftOnly &&  rect.Contains(mousePos) && (((rect.Left+rect.Width)-mousePos.X) <= 15))
        if (mi.Left && rect.Contains(mousePos))
        {
          this.ShowDropDown();
        }
        
      }
    }
commented: Will send you some Duvel this X-mass :) +14

Scott, you're an amazing man!
Your solution really works! (It had still a breakpoint set somewhere...) But I forgive you. ;) All the effort you put into this, I really appreciate this very, very much.
Thanks.

You should have seen all the breakpoints I had developing that thing, it looked like a christmas tree :P It was surprisingly difficult to get that behavior working!

Yeah, I have that often, I say: "Well THAT must be something really simple to accomplish!".
Sometimes it is :) , but most of the time it isn't :'( .
Just wanna thank you again.:)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.