簡體   English   中英

如何以編程方式關閉 datetimepicker 的下拉日歷或更新下拉日歷以反映 .Value 屬性?

[英]How can I programmatically close the dropdown calendar of a datetimepicker or update the dropdown calendar to reflect the .Value property?

請幫助?! 問題是因為我有一個使用 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";
    }

我有一些時間來弄清楚這一點。 這有點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";
    }

創建您自己的控件並添加以下內容:

#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 等。

如果只需要禁止打開下拉菜單,您可以使用更簡單的解決方案。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM