요즘 다시 방구석지니 업데이트 개발을 시작했다. 개발하고 있는 내용은 백테스트인데 백테스트 기간을 선택할 수 있는 입력창을 단순히 한구간 이라면 시작일, 종료일로 그냥 TextEdit를 사용하면 된다. 하지만 다구간일 경우 구간마다 TextEdit를 panel로 붙여야 하는데 만약 사용자가 10구간을 선택한다면... TextEdit 20개를 붙여야하는데... 노가다도 그런 노가다가 없다.
그래서 사용자 입력에 따라 구간 수가 자동으로 늘어나게 셋팅하려면 DataGridView를 사용해서 Row를 구간 수에 맞게 늘려주면 된다. 문제는 DataGridView에는 컬럼 설정에 DateTimePicker를 선택할 수 없다는 것이다.
그래서 구글링을 해봤는데 구현하는 원리는 이러하다.
1. DataGridView에서 Cell이 클릭 될 때 이벤트 발생
2. 이벤트 핸들러에서 ColumnIndex를 읽어 '시작일' 혹은 '종료일' 컬럼 일 경우 DateTimePicker 컨트롤을 생성하고 클릭된 Cell의 size, location을 DateTimePicker 컨트롤의 속성에 대입해준다.
3. 날짜를 선택한 후 DateTimePicker 컨트롤은 삭제하고 선택된 날짜는 클릭된 Cell에 기록한다.
그래서 구현한 UI는 아래와 같다.
코드는 대충 아래와 같다.
private void BackTest_Set_Port_dgv_CellClick(object sender, DataGridViewCellEventArgs e) { // ColumnIndex 1: 시작일, 3: 종료일, 5: 파일선택 if (e.RowIndex >= 0) // exclude header { if (e.ColumnIndex == 1) // 시작일 { DateTimePicker dtp = new DateTimePicker(); dtp.Format = DateTimePickerFormat.Short; dtp.Visible = true; if (BackTest_Set_Port_dgv.CurrentCell.Value != null) { dtp.Value = DateTime.Parse(BackTest_Set_Port_dgv.CurrentCell.Value.ToString()); } else { dtp.Value = DateTime.Now; } // set size and location var rect = BackTest_Set_Port_dgv.GetCellDisplayRectangle(e.ColumnIndex, e.RowIndex, true); dtp.Size = new Size(rect.Width, rect.Height); dtp.Location = new Point(rect.X, rect.Y); BackTest_Set_Port_dgv.Controls.Add(dtp); // attach events dtp.CloseUp += new EventHandler(dtp_CloseUp); dtp.TextChanged += new EventHandler(dtp_OnTextChange); }
private void dtp_OnTextChange(object sender, EventArgs e) { BackTest_Set_Port_dgv.CurrentCell.Value = ((DateTimePicker)sender).Text.ToString(); }
// on close of cell, hide dtp void dtp_CloseUp(object sender, EventArgs e) { ((DateTimePicker)sender).Visible = false; BackTest_Set_Port_dgv.Controls.Remove(((DateTimePicker)sender));
} |
댓글 없음:
댓글 쓰기