개미들을 위한 퀀트 자동 매매 프로그램 개발자 블로그입니다. 프로그래밍과 퀀트 투자를 합니다.

방구석퀀트

네이버카페 : 방구석 퀀트 놀러오세요^^ https://cafe.naver.com/conerquant 가입해 주세요.

2022년 10월 7일 금요일

C# DataGridView에 DateTimePicker 넣기

 요즘 다시 방구석지니 업데이트 개발을 시작했다. 개발하고 있는 내용은 백테스트인데 백테스트 기간을 선택할 수 있는 입력창을 단순히 한구간 이라면 시작일, 종료일로 그냥 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));

        }







댓글 없음:

댓글 쓰기

가장 많이 본 글