0

请帮忙?!问题是因为我有一个使用 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.Now 时“取消” 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";
    }
4

3 回答 3

2

我有一些时间来解决这个问题。这有点 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";
    }
于 2013-02-22T15:44:51.000 回答
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 高频!!!并且也可以与其他控件一起使用,例如 TextBox、DataGridView 等。

于 2013-08-22T22:10:24.057 回答
0

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

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

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();
    }
}
于 2021-03-10T10:12:36.243 回答