첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

■ DataGridView 클래스 : 커스텀 컨트롤 컬럼 만들기 예제

using System;
using System.Windows.Forms;

CalendarColumn calendarColumn = new CalendarColumn();

calendarColumn.Width = 120;

this.dataGridView.Columns.Add(calendarColumn);

this.dataGridView.RowCount = 5;

foreach(DataGridViewRow row in this.dataGridView.Rows)
{
    row.Cells[0].Value = DateTime.Now;
}

※ dataGridView : DataGridView 인스턴스를 가정한다.

 

■ DataGridView 클래스 : 커스텀 컨트롤 컬럼 만들기

 

▶ CalendarEditingControl.cs

using System;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 캘린더 컬럼
    /// </summary>
    public class CalendarColumn : DataGridViewColumn
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 셀 템플리트 - CellTemplate

        /// <summary>
        /// 셀 템플리트
        /// </summary>
        public override DataGridViewCell CellTemplate
        {
            get
            {
                return base.CellTemplate;
            }
            set
            {
                if(value != null &&  !value.GetType().IsAssignableFrom(typeof(CalendarCell)))
                {
                    throw new InvalidCastException("CalendarCell 타입이어야 합니다.");
                }

                base.CellTemplate = value;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - CalendarColumn()

        /// <summary>
        /// 생성자
        /// </summary>
        public CalendarColumn() : base(new CalendarCell())
        {
        }

        #endregion
    }
}

 

▶ CalendarCell.cs

using System;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 캘린더 셀
    /// </summary>
    public class CalendarCell : DataGridViewTextBoxCell
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 타입 - EditType

        /// <summary>
        /// 편집 타입
        /// </summary>
        public override Type EditType
        {
            get
            {
                return typeof(CalendarEditingControl);
            }
        }

        #endregion

        #region 값 타입 - ValueType

        /// <summary>
        /// 값 타입
        /// </summary>
        public override Type ValueType
        {
            get
            {
                return typeof(DateTime);
            }
        }

        #endregion

        #region 디폴트 신규 행 값 - DefaultNewRowValue

        /// <summary>
        /// 디폴트 신규 행 값
        /// </summary>
        public override object DefaultNewRowValue
        {
            get
            {
                return DateTime.Now;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - CalendarCell()

        /// <summary>
        /// 생성자
        /// </summary>
        public CalendarCell() : base()
        {
            this.Style.Format = "d";
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 컨트롤 초기화 하기 - InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)

        /// <summary>
        /// 편집 컨트롤 초기화 하기
        /// </summary>
        /// <param name="rowIndex">행 인덱스</param>
        /// <param name="initialFormattedValue">초기 포맷 값</param>
        /// <param name="dataGridViewCellStyle">그리드 데이터 뷰 셀 스타일</param>
        public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
        {
            base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);

            CalendarEditingControl control = DataGridView.EditingControl as CalendarEditingControl;


            if(this.Value == null)
            {
                control.Value = (DateTime)this.DefaultNewRowValue;
            }
            else
            {
                control.Value = (DateTime)this.Value;
            }
        }

        #endregion
    }
}

 

▶ CalendarColumn.cs

using System;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 캘린더 편집 컨트롤
    /// </summary>
    public class CalendarEditingControl : DateTimePicker, IDataGridViewEditingControl
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 데이터 그리드 뷰
        /// </summary>
        private DataGridView dataGridView;

        /// <summary>
        /// 값 변경 여부
        /// </summary>
        private bool valueChanged = false;

        /// <summary>
        /// 행 인덱스
        /// </summary>
        private int rowIndex;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Property
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 컨트롤 데이터 그리드 뷰 - EditingControlDataGridView

        /// <summary>
        /// 편집 컨트롤 데이터 그리드 뷰
        /// </summary>
        public DataGridView EditingControlDataGridView
        {
            get
            {
                return this.dataGridView;
            }
            set
            {
                this.dataGridView = value;
            }
        }

        #endregion

        #region 편집 패널 커서 - EditingPanelCursor

        /// <summary>
        /// 편집 패널 커서
        /// </summary>
        public Cursor EditingPanelCursor
        {
            get
            {
                return base.Cursor;
            }
        }

        #endregion

        #region 편집 컨트롤 행 인덱스 - EditingControlRowIndex

        /// <summary>
        /// 편집 컨트롤 행 인덱스
        /// </summary>
        public int EditingControlRowIndex
        {
            get
            {
                return this.rowIndex;
            }
            set
            {
                this.rowIndex = value;
            }
        }

        #endregion

        #region 편집 컨트롤 포맷 값 - EditingControlFormattedValue

        /// <summary>
        /// 편집 컨트롤 포맷 값
        /// </summary>
        public object EditingControlFormattedValue
        {
            get
            {
                return this.Value.ToShortDateString();
            }
            set
            {            
                if(value is string)
                {
                    try
                    {
                        this.Value = DateTime.Parse((string)value);
                    }
                    catch
                    {
                        this.Value = DateTime.Now;
                    }
                }
            }
        }

        #endregion

        #region 편집 컨트롤 값 변경 여부 - EditingControlValueChanged

        /// <summary>
        /// 편집 컨트롤 값 변경 여부
        /// </summary>
        public bool EditingControlValueChanged
        {
            get
            {
                return this.valueChanged;
            }
            set
            {
                this.valueChanged = value;
            }
        }

        #endregion

        #region 값 변경시 편집 컨트롤 재위치 여부 - RepositionEditingControlOnValueChange

        /// <summary>
        /// 값 변경시 편집 컨트롤 재위치 여부
        /// </summary>
        public bool RepositionEditingControlOnValueChange
        {
            get
            {
                return false;
            }
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - CalendarEditingControl()

        /// <summary>
        /// 생성자
        /// </summary>
        public CalendarEditingControl()
        {
            this.Format = DateTimePickerFormat.Short;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 편집 컨트롤 포맷 값 구하기 - GetEditingControlFormattedValue(context)

        /// <summary>
        /// 편집 컨트롤 포맷 값 구하기
        /// </summary>
        /// <param name="context">컨텍스트</param>
        /// <returns>편집 컨트롤 포맷 값</returns>
        public object GetEditingControlFormattedValue(DataGridViewDataErrorContexts context)
        {
            return EditingControlFormattedValue;
        }

        #endregion

        #region 셀 스타일 편집 컨트롤 적용하기 - ApplyCellStyleToEditingControl(dataGridViewCellStyle)

        /// <summary>
        /// 셀 스타일 편집 컨트롤 적용하기
        /// </summary>
        /// <param name="dataGridViewCellStyle">데이터 그리드 뷰 셀 스타일</param>
        public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
        {
            this.Font                    = dataGridViewCellStyle.Font;
            this.CalendarForeColor       = dataGridViewCellStyle.ForeColor;
            this.CalendarMonthBackground = dataGridViewCellStyle.BackColor;
        }

        #endregion

        #region 편집 컨트롤 입력 키 요청 여부 구하기 - EditingControlWantsInputKey(key, dataGridViewWantsInputKey)

        /// <summary>
        /// 편집 컨트롤 입력 키 요청 여부 구하기
        /// </summary>
        /// <param name="key">키</param>
        /// <param name="dataGridViewWantsInputKey">데이터 그리드 뷰 입력 키 요청 여부</param>
        /// <returns>편집 컨트롤 입력 키 요청 여부 구하기</returns>
        public bool EditingControlWantsInputKey(Keys key, bool dataGridViewWantsInputKey)
        {
            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   :

                    return true;

                default :

                    return !dataGridViewWantsInputKey;
            }
        }

        #endregion

        #region 편집용 편집 컨트롤 준비하기 - PrepareEditingControlForEdit(selectAll)

        /// <summary>
        /// 편집용 편집 컨트롤 준비하기
        /// </summary>
        /// <param name="selectAll">전체 선택 여부</param>
        public void PrepareEditingControlForEdit(bool selectAll)
        {
        }

        #endregion

        ////////////////////////////////////////////////////////////////////////////////////////// Protected

        #region 값 변경시 처리하기 - OnValueChanged(e)

        /// <summary>
        /// 값 변경시 처리하기
        /// </summary>
        /// <param name="e">이벤트 인자</param>
        protected override void OnValueChanged(EventArgs e)
        {
            this.valueChanged = true;

            this.EditingControlDataGridView.NotifyCurrentCellDirty(true);

            base.OnValueChanged(e);
        }

        #endregion
    }
}
728x90
반응형
Posted by 사용자 icodebroker

댓글을 달아 주세요