0
votes

I'm Currently developing an accounting system. As a requirement i need to design the system with less interaction with mouse.

My problem is with the datetimepicker. I'm using it over a DataGridView. when the user enter a cell, the datetime will be show but it gives me a random focus (Day,Month,Year). sometimes it focus on day, sometimes on month and sometime on Year.

does the Datetimepicker exposed its Focus? or How can i set always to Day? (dd/MM/yyyy)

Focus on Day

Focus on Year

1

1 Answers

0
votes

I don't know a better solution but this works. If I find a better one, I'll update it here. The idea is recreate the handle of your DateTimePicker. Here is the code:

bool suppressEnter = false;
//Here is the Enter event handler used for all the DateTimePicker yours
private void dateTimePickers_Enter(object sender, EventArgs e){
  if (suppressEnter) return;
  DateTimePicker picker = sender as DateTimePicker;
  picker.Hide();
  typeof(DateTimePicker).GetMethod("RecreateHandle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(picker, null);
  picker.Show();
  suppressEnter = true;
  picker.Focus();
  suppressEnter = false;
}

The code above is just a trick which doesn't use win32. The purpose is to prevent flicker when the DateTimePicker's Handle is being created. We can use the SendMessage to send the message WM_SETREDRAW to suppress painting of the control. Normally we have BeginUpdate() and EndUpdate() but I don't find those methods on DateTimePicker. This code would be more concise and not hacky at all:

[DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam);
private void dateTimePickers_Enter(object sender, EventArgs e){
   DateTimePicker picker = sender as DateTimePicker;
   //WM_SETREDRAW = 0xb
   SendMessage(picker.Handle, 0xb, new IntPtr(0), IntPtr.Zero);//BeginUpdate()
   typeof(DateTimePicker).GetMethod("RecreateHandle", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).Invoke(picker, null);
   SendMessage(picker.Handle, 0xb, new IntPtr(1), IntPtr.Zero);//EndUpdate()
}