2012-02-28 4 views
1

null 값을 입력하는 사용자를 처리하기 위해 datagriview 열을 작성했습니다 (이 경우 null 날짜로 저장되어 N/A로 표시되는 사용자의 남겨두기 날짜가 설정되지 않은 경우)nullable Datagridview DateTime 열 만들기

nullable datetimepicker를 사용하여 거의 작동하고 있지만 그리드가 null 값으로 변경되지 않으면 이전 시간 값으로 다시 전환됩니다. 행이 초기화되면 null 값으로 시작하여 정상적으로 표시됩니다.

이 바인딩 다시 모델 클래스

달력 셀

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); 
} 

편집 컨트롤은 그래서 자신에 완벽하게 작동 편집 컨트롤의 대체하려면 다음입니다 I 문제가 실제 셀 클래스에 있다고 확신하지만 문제를 발견하기에 충분한 winforms에 익숙하지 않습니다.

조언이나 심지어 포인터 만 감사 할 것입니다.

답변

0

null 값 변경이 실제로 NULL인지 또는 비어 있습니까?

장소 라인에 중단 점 : 가치와 formattedValue 당신이 기대하는 어떤 경우

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

if (formattedValue == null) 

볼 수 있습니다.

+0

답장을 보내 주셔서 감사합니다. 값을 null로 설정하면 ParseFormattedValue가 전혀 히트되지 않습니다. 날짜가 바뀌면 제대로 작동합니다. – Hudsonw

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