Search code examples
c#winformsdatetimepicker

DateTimePicker get focused field


I'm trying to determine which control (days, months, years) is selected (highlighted) in a DateTimePicker (WinForms) application. Is there a property, which indicates which control is selected? If so, can I programmatically change just that controls value from another control?

Is there a way to get the focused control of a DateTimePicker?


Solution

  • Short answer: No, not easily.

    DateTimePicker is basically a wrapper around SysDateTimePick32 and doesn't expose any easy to use properties for determining which child window is selected when ShowUpDown is set to true. It doesn't even have private members in its source code that it uses - it's basically just forwarding things on to the underlying com control, ala UnsafeNativeMethods.SendMessage

    One way is to send an up then a down and check which part changes. Here's a sample. Create a new winforms application, then add a DateTimePicker, Label and Button. After that, copy the code below into your form1.cs after the using statements:

    namespace WindowsFormsApplication1
    {
        public partial class Form1 : Form
        {
            public enum DatePart
            {
                YEAR,
                MONTH,
                DAY
            }
    
            public DatePart part { get; set; }
            private DateTime previous { get; set; }
            private bool checkSelectedPart { get; set; }
    
    
            public Form1()
            {
                InitializeComponent();
    
    
                dateTimePicker1.ValueChanged += DateTimePicker1_ValueChanged;
                dateTimePicker1.KeyPress += DateTimePicker1_KeyPress;
                previous = dateTimePicker1.Value;
    
            }
    
            private void DateTimePicker1_KeyPress(object sender, KeyPressEventArgs e)
            {
    
            }
    
            private void DateTimePicker1_ValueChanged(object sender, EventArgs e)
            {
                if (checkSelectedPart)
                {
                    var dtp = sender as DateTimePicker;
                    TimeSpan change = (dtp.Value - previous);
                    var dayChange = Math.Abs(change.Days);
                    if (dayChange == 1)
                        part = DatePart.DAY;
                    else if (dayChange >= 365)
                        part = DatePart.YEAR;
                    else
                        part = DatePart.MONTH;
    
                    previous = dtp.Value;
    
                    label1.Text = part.ToString();
                }
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                checkSelectedPart = true;
                dateTimePicker1.Focus();
                SendKeys.SendWait("{UP}");
                SendKeys.SendWait("{DOWN}");
                checkSelectedPart = false;
                button1.Focus();
            }
        }
    }