如何以编程方式关闭datetimepicker的下拉日历或更新下拉日历以反映.Value属性?

时间:2013-02-21 23:33:49

标签: c# .net winforms datetimepicker

帮助,拜托?!问题是因为我有一个旧的usercontrol,它使用了datetimepicker控件。如果datetimepicker的文本框中没有显示日期,则.Value属性设置为DateTimePicker.MinimumDateTime。如果.Value是DateTimePicker.MinimumDateTime,OnValueChanged会将CustomFormat更新为“”。否则,CustomFormat是“yyy-MM-dd hh:mm:ss tt”。

问题==>在DropDown事件中,我检查最小日期时间。如果.Value等于那个,那么我将.Value更新为DateTime.Now。显示下拉日历时,日历设置为1753-01-01,而文本框(.Value)显示DateTime.Now。

如何让日历显示与DropDown事件中更新的.Value属性相对应的日期?当值从DateTimePicker.MinimumDateTime更改为DateTime时,即使有一种方法可以'取消'DateTimePicker上的第一个DropDown事件。现在我认为这可以工作,因为第二次(以及随后的时间)下拉列表日历显示日历正确匹配文本框中显示的日期(DateTimePicker.Value)。

以下是我连接到有问题的DateTimePicker的事件的代码:

    private void ValueDatetimePickerOnKeyUp(Object sender, KeyEventArgs e)
    {
        if (e.KeyCode != Keys.Delete && e.KeyCode != Keys.Back)
            return;
        var dp = (DateTimePicker)sender;
        if (dp == null)
            return;
        dp.Value = DateTimePicker.MinimumDateTime;
    }

    private void ValueDatetimePickerDropDown(Object sender, EventArgs e)
    {
        var dp = (DateTimePicker)sender;
        if (dp == null)
            return;
        if (dp.Value == DateTimePicker.MinimumDateTime)
            dp.Value = DateTime.Now;
    }

    private void ValueDatetimePickerValueChanged(Object sender, EventArgs e)
    {
        var dp = (DateTimePicker)sender;
        if (dp == null)
            return;
        dp.CustomFormat = dp.Value == DateTimePicker.MinimumDateTime ? " " : "yyyy-MM-dd hh:mm:ss tt";
    }

3 个答案:

答案 0 :(得分:1)

我有时间想出这个。它有点hacky,但基本上在datetimepicker的DropDown事件处理程序中将ShowUpDown设置为true,然后调用Closeup事件处理程序将ShowUpDown设置为false。这将关闭下拉日历并强制用户再次打开它,然后将在日历上显示正确的日期,而不是1/1/1753。 OnKeyUp事件处理程序只允许用户在遇到DEL或Backspace键时删除datetimepicker的文本框值。

    private void ValueDatetimePickerOnKeyUp(Object sender, KeyEventArgs e)
    {
        //if user presses backspace or delete key then clear the date/time
        if (e.KeyCode != Keys.Delete && e.KeyCode != Keys.Back)
            return;
        var dp = (DateTimePicker)sender;
        if (dp == null)
            return;
        dp.Value = DateTimePicker.MinimumDateTime;
    }

    private void ValueDatetimePickerCloseUp(Object sender, EventArgs e)
    {
        var dp = (DateTimePicker) sender;
        if(dp == null)
            return;
        dp.ShowUpDown = false;
    }

    private void ValueDatetimePickerDropDown(Object sender, EventArgs e)
    {
        var dp = (DateTimePicker)sender;
        if (dp == null)
            return;
        if (dp.Value == DateTimePicker.MinimumDateTime)
        {
            dp.Value = DateTime.Now;
            dp.ShowUpDown = true;
            Invoke((MethodInvoker) (() => ValueDatetimePickerCloseUp(dp, new EventArgs())));
        }
    }

    private void ValueDatetimePickerValueChanged(Object sender, EventArgs e)
    {
        var dp = (DateTimePicker)sender;
        if (dp == null)
            return;
        dp.CustomFormat = dp.Value == DateTimePicker.MinimumDateTime ? " " : "yyyy-MM-dd HH:mm:ss tt";
    }

答案 1 :(得分:0)

创建自己的控件并添加:

#region IsInputKey(Keys keyData)
        protected override bool IsInputKey(Keys keyData)
        {
            if (keyData == Keys.Tab
                //|| keyData.Equals(Keys.Up)
                //|| keyData.Equals(Keys.Down)
                //|| keyData.Equals(Keys.Left)
                //|| keyData.Equals(Keys.Right)
                || keyData.Equals(Keys.Enter)
                || keyData.Equals(Keys.Escape)
                || keyData.Equals(Keys.Space)
                )
                return true;

            return base.IsInputKey(keyData);
        }
        #endregion

这将允许您想要传递KeyDown事件的所有密钥。 ; D hf !!! 并使用另一个控件,如TextBox,DataGridView等

答案 2 :(得分:0)

如果只需要禁止打开下拉菜单,您可以使用更简单的解决方案。

只需在 DropDown 事件中切换 ShowUpDown 属性即可。 将this更改为您的控件名称。

private void MyDropDown(object sender, EventArgs e)
{
    bool value = this.ShowUpDown;
    this.SuspendLayout();
    this.ShowUpDown = !value;
    this.ShowUpDown = value;
    this.ResumeLayout();
}

添加事件处理程序。

this.DropDown += MyDropDown;

将 DoubleBuffered 属性设置为 true 以避免闪烁可能会很方便。

Type type = this.GetType();
System.Reflection.PropertyInfo property;
property = type.GetProperty("DoubleBuffered", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
property.SetValue(control, true, null);

或者,您可以检查 ShowUpDown 属性是否已经为 false,因此它仅适用于日历下拉菜单。

private void MyDropDown(object sender, EventArgs e)
{
    if (this.ShowUpDown == false)
    {
        this.SuspendLayout();
        this.ShowUpDown = true;
        this.ShowUpDown = false;
        this.ResumeLayout();
    }
}