2012-02-28 71 views
1

我正在寫一個datagriview列來處理用戶輸入空值(在這種情況下,如果沒有爲用戶設置保留日期,它將存儲爲空並顯示爲N/A)創建一個可爲空的Datagridview日期時間列

我已經使用可空datetimepicker幾乎得到它的工作,但網格沒有拿起更改爲空值,它只是切換回舊的時間值。當行被初始化時,它以一個空值開始,它顯示正常。

然後,這是數據綁定回模型類

日曆細胞

public class CtlDataGridViewNullableCalendarCell : DataGridViewTextBoxCell 
{ 

public CtlDataGridViewNullableCalendarCell() 
    : base() 
{ 
    this.Style.Format = "d"; 
} 

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); 
    CtlCalendarNullableEditingControl ctl = DataGridView.EditingControl as CtlCalendarNullableEditingControl; 
    ctl.Value = (DateTime?)this.Value; 

    // a hacky way of getting the DateTimePicker to reset its focus, rather than remembering which date part was previously focussed 
    DateTimePickerFormat format = ctl.Format; 
    ctl.Format = DateTimePickerFormat.Custom; 
    ctl.Format = format; 
} 
public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter) 
{ 
    if (formattedValue == null) 
     return null; 
    else 
     return (formattedValue as DateTime?).Value.Date; 
} 
public override Type EditType 
{ 
    get 
    { 
     // Return the type of the editing control that CalendarCell uses. 
     return typeof(CtlCalendarNullableEditingControl); 
    } 
} 

public override Type ValueType 
{ 
    get 
    { 
     // Return the type of the value that CalendarCell contains. 
     return typeof(DateTime?); 
    } 
} 

public override object DefaultNewRowValue 
{ 
    get 
    { 
     // Use the current date as the default value. 
     return null; 
    } 
} 

#endregion 
} 

的編輯控制

class CtlCalendarNullableEditingControl : CtlNullableDateTimePicker, IDataGridViewEditingControl 
{ 
DataGridView _dataGridView; 
private bool _valueChanged = false; 
int _rowIndex; 

public object EditingControlFormattedValue 
{ 
    get 
    { 
     return this.Value; 
    } 
    set 
    { 
     if (value is string) 
      if ((string)value == string.Empty) 
       value = null; 
      else 
       value = DateTime.Parse((string)value); 

    } 
} 

public object GetEditingControlFormattedValue(
    DataGridViewDataErrorContexts context) 
{ 
    return EditingControlFormattedValue as DateTime?; 
} 

public void ApplyCellStyleToEditingControl(
    DataGridViewCellStyle dataGridViewCellStyle) 
{ 
    this.Font = dataGridViewCellStyle.Font; 
    this.CalendarForeColor = dataGridViewCellStyle.ForeColor; 
    this.CalendarMonthBackground = dataGridViewCellStyle.BackColor; 
} 

public int EditingControlRowIndex 
{ 
    get 
    { 
     return _rowIndex; 
    } 
    set 
    { 
     _rowIndex = value; 
    } 
} 

public bool EditingControlWantsInputKey(
    Keys key, bool dataGridViewWantsInputKey) 
{ 
    // Let the DateTimePicker handle the keys listed. 
    switch (key & Keys.KeyCode) 
    { 
     case Keys.Left: 
     case Keys.Up: 
     case Keys.Down: 
     case Keys.Right: 
     case Keys.Home: 
     case Keys.End: 
     case Keys.PageDown: 
     case Keys.PageUp: 
     case Keys.Delete: 
     case Keys.Back: 
      return true; 
     default: 
      return false; 
    } 
} 

public DataGridView EditingControlDataGridView 
{ 
    get 
    { 
     return _dataGridView; 
    } 
    set 
    { 
     _dataGridView = value; 
    } 
} 

public bool EditingControlValueChanged 
{ 
    get 
    { 
     return _valueChanged; 
    } 
    set 
    { 
     _valueChanged = value; 
    } 
} 


#region -- DateTimePicker overrides -- 

/// <summary> 
/// Handle the OnValueChanged event from the <see cref="DateTimePicker"/> and ensure the change propagates to the grid. 
/// </summary> 
/// <param name="eventargs"></param> 
protected override void OnValueChanged(EventArgs eventargs) 
{ 
    // Notify the DataGridView that the contents of the cell have changed. 
    _valueChanged = true; 
    this.EditingControlDataGridView.NotifyCurrentCellDirty(true); 
    base.OnValueChanged(eventargs); 
} 

編輯控制完美的作品在它自己的這樣的覆蓋我確定問題存在於實際的單元類中,但我不熟悉winforms足以發現問題。

建議,甚至只是指針會受到感謝。

回答

0

對空值的改變實際= NULL,還是爲空?

廣場上的線條一個破發點:

if ((string)value == string.Empty) 

if (formattedValue == null) 

,看是否值和FormattedValue的是你期待什麼。

+0

感謝您的回覆。當值設置爲null時,ParseFormattedValue根本不會被打中。當它更改爲日期時,它工作正常。 – Hudsonw 2012-02-29 15:04:10

0
public override object ParseFormattedValue(object formattedValue, DataGridViewCellStyle cellStyle,TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter) 
{ 
    if (formattedValue != DBNull.Value && formattedValue.ToString() != "") 
    { 
    return base.ParseFormattedValue(formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter); 
    } 
    else 
    { 
    return DBNull.Value; 
    } 
} 
+0

你可以給你的代碼添加一個解釋嗎? – secretformula 2014-06-26 15:39:58

相關問題