【问题标题】:DateTimePicker needs multiple clicks of checkbox to fire OnValueChangedDateTimePicker 需要多次单击复选框才能触发 OnValueChanged
【发布时间】:2014-01-20 19:05:44
【问题描述】:

我正在修改一些具有自定义日历控件的代码,将DateTimePicker 用于DataGridView。我已经设置了ShowCheckBox = true,并且我试图强制它在用户单击复选框时将日期的值更改为空(通过更改日期的CustomFormat),这有效。我的问题是在复选框上单击太多次才能更改 DateFormat。我的基本 CalendarColumn 来自 http://msdn.microsoft.com/en-us/library/7tas5c80.aspx,但它不包含复选框并且不允许空值。

我的OnValueChanged() 代码是:

    protected override void OnValueChanged(EventArgs eventargs)
    {
        // Notify the DataGridView that the contents of the cell 
        // have changed.
        base.OnValueChanged(eventargs);

        if (this.Checked)
        {
            this.Checked = true;
            this.Format = DateTimePickerFormat.Short;
        } else if (!this.Checked)
        {
            this.Format = DateTimePickerFormat.Custom;
            this.CustomFormat = " ";
        }
    }

第一次单击复选框(当它的值被选中时)会使日期变灰,但不会触发 OnValueChanged() 方法,第二次单击将其设置回“选中”并触发事件,第三次单击单击将CustomFormat 设置为“”,因此应显示空日期。

我做了一些研究,我认为我的问题与在第一次点击时获得单元格的焦点有关,但如果我将支票放入 onGotFocus(),单击将显示/隐藏日期格式,但是当我在取消选中复选框后单击另一个单元格时,它仍然将CustomFormat 设置为“”而不是DateTimePickerFormat.Short

关于类似主题的其他答案请参阅http://www.mofeel.net/70-microsoft-public-dotnet-framework-windowsforms/8806.aspx,但我对如何将其合并到我的代码中感到困惑。我还没有发布整个课程,但是如果有人认为这会有所帮助,我可以这样做吗?

【问题讨论】:

    标签: c# winforms datagridview custom-datetimepicker


    【解决方案1】:

    一位同事帮我解决了这个问题。我会尽力解释:

    我的OnValueChanged() 方法最终看起来像:

    protected override void OnValueChanged(EventArgs eventargs)
    {
        valueChanged = true;
        // Notify the DataGridView that the contents of the cell 
        // have changed.
    
        this.EditingControlDataGridView.NotifyCurrentCellDirty(true);
        base.OnValueChanged(eventargs);
    
        isChecked();
    }
    
    public bool isChecked()
    {
        bool isChecked = false;
         if (this.Checked)
        {
            this.Checked = true;
            this.Format = DateTimePickerFormat.Short;
            isChecked = true;
        }
        else if (!this.Checked)
        {
            this.Format = DateTimePickerFormat.Custom;
            this.CustomFormat = " ";
            isChecked = false;
        }
         return isChecked;
    }
    

    他还添加了这些方法:

    protected override void OnClick(EventArgs e)
    {
        isChecked();
        base.OnClick(e);
    }     
    
    public object EditingControlFormattedValue
    {
        get
        {
            if (!this.Checked)
            {
                return String.Empty;                    
            }
            else
            {
                if (this.Format == DateTimePickerFormat.Custom)
                {
                    return this.Value.ToString();
                }
                else
                {
                    return this.Value.ToShortDateString();
                }
            }
        }
        set
        {
            string newValue = value as string;
            if (!String.IsNullOrEmpty(newValue))
            {
                this.Value = DateTime.Parse(newValue);
            }
        }
    }
    

    InitializaEditingControl 也被编辑为:

     public override void InitializeEditingControl(int rowIndex, object
            initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
     {
         // Set the value of the editing control to the current cell value. 
         base.InitializeEditingControl(rowIndex, initialFormattedValue,
             dataGridViewCellStyle);
         ctl = DataGridView.EditingControl as CalendarEditingControl;
         // ctl.Invalidated += new InvalidateEventHandler(ctl_Invalidated);
         ctl.ValueChangedSpecial += new EventHandler(ctl_ValueChangedSpecial);
         if (rowIndex >= 0)
         {
             try
             {                    
                 if (String.IsNullOrEmpty(this.Value.ToString()))
                 {
                     ctl.Checked = false;
                     ctl.Format = DateTimePickerFormat.Custom;
                     ctl.CustomFormat = " ";
                 }
                 else
                 {
                     ctl.Checked = true;
                     ctl.Value = (DateTime)this.Value;
                     ctl.Format = DateTimePickerFormat.Short;            
                 }
             }
             catch (ArgumentOutOfRangeException aex)
             {
                 //MessageBox.Show("ERROR. " + aex.Message);
                 ctl.Value = (DateTime)this.DefaultNewRowValue;
             }
         }
     }
    

    然后它起作用了。

    这个答案几乎肯定不能令人满意,但未回答的问题对任何人都没有帮助,所以希望这里的一些东西可以帮助其他人。

    【讨论】:

      猜你喜欢
      • 2017-09-23
      • 2014-08-08
      • 2010-12-04
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2015-12-24
      • 1970-01-01
      • 2011-07-29
      相关资源
      最近更新 更多