c# - DateTimePicker 需要多次单击复选框才能触发 OnValueChanged

标签 c# winforms datagridview custom-datetimepicker

我正在修改一些具有自定义日历控件的代码,其中使用 DataGridViewDateTimePicker 。我已经设置了 ShowCheckBox = true ,并且当用户单击复选框时,我试图强制它将日期值更改为 null(通过更改日期),有效。我的问题是,需要多次单击复选框才能更改日期格式。我的基本日历列来自 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。简短

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

最佳答案

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

我的 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;
         }
     }
 }

然后就成功了。

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

关于c# - DateTimePicker 需要多次单击复选框才能触发 OnValueChanged,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19313741/

相关文章:

c# - 您如何在 LINQ 中进行自定义排序,最后始终为 null?

c# - 是否可以创建无论电池状态如何都保持事件状态的 UWP 服务?

c# - DevExpress ComboBoxEdit 数据源

c# - 异步方法的延迟进度报告

c# - 阻止 DataGridView 在面板下流动?

winforms - Winform Framework 2.0中ListView和DataGridView的滚动条始终可见

c# - GridView RowCommand 第一次未触发

c# - 如何根据数据库中的现有条目快速减少数据表

c# - 如何使列完全填充数据 GridView

c# - DataGridViewCell.FormattedValue 是如何更新的?