C# DateTimePicker获取焦点字段

C# DateTimePicker获取焦点字段,c#,winforms,datetimepicker,C#,Winforms,Datetimepicker,我试图确定在日期时间选择器(WinForms)应用程序中选择(突出显示)哪个控件(天、月、年)。是否有一个属性指示选择了哪个控件?如果是这样,我是否可以通过编程从另一个控件更改该控件的值 有没有办法获得日期时间选择器的集中控制?简短回答:不,不容易 DateTimePicker基本上是SysDateTimePick32的包装器,当ShowDown设置为true时,它不公开任何易于使用的属性来确定选择哪个子窗口。它使用的源代码中甚至没有私有成员——它基本上只是将内容转发到底层的com控件ala U

我试图确定在
日期时间选择器
(WinForms)应用程序中选择(突出显示)哪个控件(天、月、年)。是否有一个属性指示选择了哪个控件?如果是这样,我是否可以通过编程从另一个控件更改该控件的值


有没有办法获得日期时间选择器的集中控制?

简短回答:不,不容易

DateTimePicker基本上是SysDateTimePick32的包装器,当ShowDown设置为true时,它不公开任何易于使用的属性来确定选择哪个子窗口。它使用的源代码中甚至没有私有成员——它基本上只是将内容转发到底层的com控件ala UnsafeNativeMethods.SendMessage

一种方法是先发送一个向上键,然后发送一个向下键,然后检查哪些零件发生了更改。这是一个样品。创建一个新的winforms应用程序,然后添加DateTimePicker、标签和按钮。之后,在using语句之后,将以下代码复制到form1.cs中:

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();
        }
    }
}

简短回答:不,不容易

DateTimePicker基本上是SysDateTimePick32的包装器,当ShowDown设置为true时,它不公开任何易于使用的属性来确定选择哪个子窗口。它使用的源代码中甚至没有私有成员——它基本上只是将内容转发到底层的com控件ala UnsafeNativeMethods.SendMessage

一种方法是先发送一个向上键,然后发送一个向下键,然后检查哪些零件发生了更改。这是一个样品。创建一个新的winforms应用程序,然后添加DateTimePicker、标签和按钮。之后,在using语句之后,将以下代码复制到form1.cs中:

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();
        }
    }
}

你的最终目标是什么?您是否能够通过更新Value属性来完成您想要的任务?我似乎还记得一种确定复合控件中哪个控件具有焦点的方法,但我现在画的是空白,因为我已经好几年没有在WinForms中接触任何控件了。目标是更改DateTime单个值(就像我在DateTimePicker中选择一列并在键盘上键入新值一样)。但是,我不想使用系统键盘。我希望DateTimePicker的聚焦子控件会有一些属性,但并不像@Erikestt所描述的那样,在复合控件中确定哪个控件具有焦点的方法,您是指IMessageFilter吗?您的最终目标是什么?您是否能够通过更新Value属性来完成您想要的任务?我似乎还记得一种确定复合控件中哪个控件具有焦点的方法,但我现在画的是空白,因为我已经好几年没有在WinForms中接触任何控件了。目标是更改DateTime单个值(就像我在DateTimePicker中选择一列并在键盘上键入新值一样)。但是,我不想使用系统键盘。我希望DateTimePicker的聚焦子控件会有一些属性,但并没有@Erikestt所描述的方法来确定哪个控件在复合控件中有焦点,你是指IMessageFilter吗?我担心它是这样做的。感谢您的回答。您可以做的一件事是通过向上发送一个键,然后向下发送一个键来跟踪日期的更改,并检查ValueChanged事件,通过从currentDate减去previousDate查看时间跨度来查看日期的哪一部分已更改。我已经修改了我的答案,加入了一个如何实现这个非常好的解决方案的示例,避免了我创建messagefilter或在UI中制造混乱。在UserControl中为我感谢了很多人。我担心是这样做的。感谢您的回答。您可以做的一件事是通过向上发送一个键,然后向下发送一个键来跟踪日期的更改,并检查ValueChanged事件,通过从currentDate减去previousDate查看时间跨度来查看日期的哪一部分已更改。我已经修改了我的答案,加入了一个如何实现这个非常好的解决方案的示例,避免了我创建messagefilter或在UI中制造混乱。在UserControl中为我感谢了很多人。