반응형

Calendar 컬럼(Column)을 표현하기 위해 사전 준비 작업과 YearMonthWeekNoDayHeader, YearMonthWeekNoDayHeaderGenerator, HeaderBuilder를 살펴 보았고, 실제 WANIGrid Control 영역을 살펴보자.

 

새로운 변수를 추가하기로 하자.

    private int currentCol = 0; //현재 첫페이지를 저장하기 위한 변수

    private SolidBrush holidayColorBrush = new SolidBrush(Color.LightSkyBlue); //휴일색상

    private bool fixedColEditable = true;   //고정 컬럼 수정 여부

 

속성(Property)설정을 아래와 같이 한다.

    /// <summary>
    /// 휴일 색상으로 채워주는 Brush 값을 가져오거나 설정한다.
    /// </summary>
    public SolidBrush HolidayColorBrush
    {
        get { return holidayColorBrush;}
        set { holidayColorBrush = value; }
    }

 

    /// <summary>
    /// 고정 컬럼 수정여부
    /// </summary>
    public bool FixedColEditable
    {
        get { return fixedColEditable; }
        set { fixedColEditable = value; }
    }

 

WANIGrid 영역의 Event 처리 부분인 WANIGrid.Event.cs 파일을 추가로 보완하기로 하자.

Calendar 컬럼 영역의 헤드를 마우스 클릭 했을 때 특정 컬럼이 선택되지 않도록 처리하기 위해서 마우스 좌측 버튼이 헤더 영역에서 클릭 이벤트가 있는지 체크해야 한다.

이러한 이벤트를 잡기 위해서 MouseLeftButtonClickInTopHeadHeight 메소드를 찾아서 아래의 파란색 부분을 추가한다.

 

    /// <summary>
    /// WANIGrid의 Header 영역에서 마우스 좌측 버튼 클릭 시
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void MouseLeftButtonClickInTopHeadHeight(object sender, MouseEventArgs e)
    {
        selectedRows.Clear();

        //컬럼이 존재할 경우
        if (grid.GridHeaderList.Count > 0)
        {
            int col = GetColFromX(e.X);
            if (col < 0) return; //col값이 -1이면 처리하지 않음                

            //Calendar 날짜 컬럼은 선택되지 않도록 처리
            if (grid.GridHeaderList[col].IsDate) return;

            //Control Key를 누르지 않은 상태에서 컬럼을 선택했을 경우
            if (Control.ModifierKeys != Keys.Control && Control.ModifierKeys != Keys.Shift)
            {

            :

            :

            }

         :

        }

      :

    }

  

Calendar 컬럼의 헤더 영역을 마우스 이동 시 컬럼 폭 조정이 되지 않도록 처리해야 한다.

WANIGrid_MouseMove 이벤트의 폭을 변경하는 영역에 해당 컬럼이 Calendar정보를 가진 컬럼인지 체크하는 부분을 추가해야 한다. 아래의 파란색 부분을 참조하자.

    /// <summary>
    /// Mouse Move Event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void WANIGrid_MouseMove(object sender, MouseEventArgs e)
    {
        //vSpliteLineMouseDown이 true 이면 마우스 버튼이 눌러진 상태에서 이동 중인 상태임.
        if (vSpliteLineMouseDown)
        {
            if (Math.Abs(e.X - lastMousePoint.X) > 4) DrawVSpliteLine(new Point(e.X, e.Y));
            return;
        }         

          :
        if (grid.GridHeaderList.Count > 0 && e.Y < topHeaderHeight)
        {  
            :    
            //Header의 컬럼과 컬럼 간의 경계선 상에 마우스 포인트가 위치했을 경우
            if (!grid.GridHeaderList[i].IsDate && (e.X > colLine - 2 && e.X < colLine + 2))
            {
                Cursor = Cursors.VSplit;
                resizeCol = i;
                if (resizeCol >= grid.GridHeaderList.Count) resizeCol = grid.GridHeaderList.Count - 1;
                break;
            }
            :
        } else
        {
                        :
                        //Header의 컬럼과 컬럼 간의 경계선 상에 마우스 포인트가 위치했을 경우
                        if (!grid.GridHeaderList[i].IsDate && (e.X > colLine - 2 && e.X < colLine + 2))
                        {
                            Cursor = Cursors.VSplit;
                            resizeCol = i;
                            if (resizeCol >= grid.GridHeaderList.Count) resizeCol = grid.GridHeaderList.Count - 1;
                            break;
                        }
                    :
                        //Header의 컬럼과 컬럼 간의 경계선 상에 마우스 포인트가 위치했을 경우
                        if (!grid.GridHeaderList[i].IsDate && (e.X > colLine - 2 && e.X < colLine + 2))
                        {
                            Cursor = Cursors.VSplit;
                            resizeCol = i;
                            if (resizeCol >= grid.GridHeaderList.Count) resizeCol = grid.GridHeaderList.Count - 1;
                            break;
          :
        }
    }

 

컬럼의 데이터 수정 시 RowCollection 타입의 rows변수의 속성인 DataRow에  값이 null일 경우에 Event 처리가 되지 않도록 한다. 아래의 파란색 부분을 추가한다.

    /// <summary>
    /// TextBox인 editBox의 TextChanged Event
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void EditBox_TextChanged(object sender, EventArgs e)
    {
        :

        if (rows[ActiveCell.Row].DataRow == null) return;
        DataRow row = rows[ActiveCell.Row].DataRow;
        Header header = grid.GridHeaderList.Where(x => x.Index == ActiveCell.Col).FirstOrDefault();
        if (header != null)
        {
            if (ActiveCell_ActvieCol > -1) row[header.ColumnId] = editBox.Text;
        }
    }

 

WANIGrid Control상에서 Control키를 누르고 + 또는 - 키를 눌렀을 때 Calendar 컬럼의 Width를 1씩 줄여서 Display하는 KeyDown 이벤트를 추가한다.

    /// <summary>
    /// Control Key + : 폭 넓게
    /// Control Key - : 폭 좁게
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private void WANIGrid_KeyDown(object sender, KeyEventArgs e)
    {
        if (this.grid.GridDisplayType != GridType.YearMonthWeekNoDayType) return;            

        if (e.Control && e.KeyCode == Keys.Add)
        {
            foreach(YearMonthWeekNoDayHeader header in this.grid.GridHeaderList)
            {
                if (header.IsDate) header.Width += 1;
            }
        } else if (e.Control && e.KeyCode == Keys.Subtract)
        {
            foreach (YearMonthWeekNoDayHeader header in this.grid.GridHeaderList)
            {
                if (header.IsDate) header.Width -= 1;
            }
        }
        Invalidate();
    }

 

WANIGrid.Method.cs파일의 추가/보완할 부분들을 살펴보자

먼저 Grid 컬럼의 Header를 생성해서 추가하는 SetHeader 메소드를 살펴보자.

추가/변경 되는 부분은 아래의 파란색 부분을 참조하자.

    /// <summary>
    /// Grid 컬럼의 Header를 생성해서 추가한다.
    /// </summary>
    /// <param name="headerBuilder"></param>
    public void SetHeader(HeaderBuilder headerBuilder)
    {
        if (grid == null) grid = new WANI_Grid.Grid.Grid();
        if (headerBuilder != null)
        {
            grid.HeaderGen = headerBuilder.HeaderGen;
            topHeaderHeight = headerBuilder.HeaderGen.TopHeaderHeight;
            grid.DicWeekDay = headerBuilder.DicWeekDay;
            grid.DicMonthDay = headerBuilder.DicMonthDay;
        }

        grid.GridDisplayType = headerBuilder.GridDisplayType;
        grid.TopHeaderHeight = headerBuilder.HeaderGen.TopHeaderHeight;
        InitializeScollBar();

        //dataSource가 null일 경우 Header정보를 근간으로 DataTable 생성
        if (dataSource != null)
        {
            dataSource.Clear();
            dataSource = null;
            rows.Clear();
            rowHeight = 0;
            rowsCount = 0;
            selectedCols.Clear();
            selectedRows.Clear();
            allRowsHeight = 0;                
            vScrollBar.Maximum = allRowsHeight;
            firstVisibleCol = 0;
            lastVisibleCol = 0;
            firstVisibleRow = 0;
            lastVisibleRow = 0;
        }

        if (dataSource == null)
        {
            dataSource = new DataTable();
            foreach (Header hd in grid.HeaderGen.GetHeaders())
            {
                dataSource.Columns.Add(new DataColumn(hd.ColumnId, typeof(string)));
            }               
        }                                    
    }

 

Control의 Backgroud 그리는 메소드인 DrawBackground 메소드의 추가 된 부분은 아래와 같다.

    /// <summary>
    /// Control의 Backgroud 그리기
    /// </summary>
    /// <param name="g"></param>
    /// <param name="rc"></param>
    private void DrawBackground(Graphics g, Rectangle rc)
    {
        g.DrawRectangle(new Pen(SystemColors.Control, 2), 0, 0, rc.Width, rc.Height);
        rc.Inflate(-1, -1);
        g.FillRectangle(new SolidBrush(SystemColors.ControlLightLight), rc);

        int lastFixedCol = GetLastFixedCol();
        if (lastFixedCol == -1)
        {
            DrawDefaultWANIGridControl(g, rc);
            return;
        }
        //고정 컬럼으로 지정이 가능한 영역은 Calendar 컬럼이 아닌 경우에만 가능

        //Grid의 GridHeaderList 정보를 가져와서 YearMonthHeader Type의 변환 후 GetDateTime이 DateTime.MinValue 보다 작은 경우는

        //Calendar 컬럼이 아님.
        int enableFixCol = 0;
        for (int i = 0; i <= lastFixedCol; i++)
        {
            YearMonthWeekNoDayHeader yearMonthHeader = grid.GridHeaderList[i] as YearMonthWeekNoDayHeader;
            if (yearMonthHeader != null && yearMonthHeader.GetDateTime <= DateTime.MinValue) enableFixCol = i;
        }
        if (lastFixedCol > enableFixCol) lastFixedCol = enableFixCol;

        //선택된 컬럼의 Background를 그린다.
        SelectedColChangeBackground(g, lastFixedCol);

        //선택된 행(Row)의 Background를 그린다.
        SelectedRowChangeBackground(g, lastFixedCol);

        //휴일 색상을 그린다
        FillHolidayBackgroundColor(g);
    }

 

휴일 컬럼의 배경 색상을 칠하는 메소드인 FillHolidayBackgroundColor 메소드를 추가하도록 한다.

    private void FillHolidayBackgroundColor(Graphics g)
    {
        if (grid.GridDisplayType != GridType.YearMonthWeekNoDayType) return;
        //고정 컬럼이 없을 경우
        if (colFixed == 0)
        {
            int startX = leftHeaderWidth;
            for (int i = firstVisibleCol; i <= lastVisibleCol; i++)
            {
                YearMonthWeekNoDayHeader yearMonthHeader = grid.GridHeaderList[i] as YearMonthWeekNoDayHeader;                    
                if (yearMonthHeader.IsHoliday)
                {                        
                    g.FillRectangle(holidayColorBrush, startX + 1, topHeaderHeight + 1, yearMonthHeader.Width, 

                                         allRowsHeight - (rowHeight * firstVisibleRow) + 1);                        
                }
                startX += yearMonthHeader.Width;
            }
        } else
        {
            int startX = leftHeaderWidth + GetFixedColWidth();                
            for (int i = firstVisibleCol + colFixed; i <= lastVisibleCol && i < grid.GridHeaderList.Count; i++)
            {                    
                YearMonthWeekNoDayHeader yearMonthHeader = grid.GridHeaderList[i] as YearMonthWeekNoDayHeader;                    
                if (yearMonthHeader.IsHoliday)
                {                        
                    g.FillRectangle(holidayColorBrush, startX + 1, topHeaderHeight + 1, yearMonthHeader.Width, 

                                         allRowsHeight - (rowHeight * firstVisibleRow) + 1);                        
                }
                startX += grid.GridHeaderList[i].Width;
            }
        }
    }

 

Header영역을 그리는 DrawHeaders메소드에서 Parameter가 하나 더 추가 되었다. 추가된 파라미터는 고정 컬럼의 수정여부에 따라 고정 컬럼의 값을 변경 또는 변경할 수 없도록 지정하는 부분이다.

    /// <summary>
    /// Grid의 Header 그리기
    /// </summary>
    /// <param name="g"></param>
    /// <param name="rc"></param>

    /// <param name="colFixed"></param> 

    /// <param name="fixedColEditable"></param>
    private void DrawHeaders(Graphics g, Rectangle rc, int colFixed, bool fixedColEditable)
    {
        if (grid != null)
        {
            grid.DrawHeader(g, rc, rc.Width, colFixed, fixedColEditable);                
        }
    }

 

grid.GridHeaderList의 IsDate가 true인 경우에 선택된 Active Cell의 경우 Active Cell 표시가 되지 않도록 한다.

    /// <summary>
    /// Active Cell을 표기한다.
    /// </summary>
    /// <param name="g"></param>
    private void DrawActiveCell(Graphics g)
    {
        if (ActiveCell.Row != -1 && ActiveCell.Col != -1)
        {
            //Calendar 날짜 컬럼은 Active Cell이 되지 않도록 처리
            if (grid.GridHeaderList[ActiveCell.Col].IsDate) return;

            //파선 패턴 설정
            float[] dashValues = { 1, 1, 1, 1 };
            Pen grayPen = new Pen(Color.Gray, 1);
            grayPen.DashPattern = dashValues;
            g.DrawRectangle(grayPen, GetSelectedCellRect(ActiveCell.Row, ActiveCell.Col));
        }
    }

 

지금까지의 작업으로 완성된 WANIGrid Test 화면은 아래와 같다.

아래의 테스트 화면에 대한 사용 설명은 다음 시간에 간단히 정리하도록 하겠다.

[그림 24-1] WANIGrid Test 화면

 

그외에도 가로/세로 스크롤바를 재계산하는 ReCalcScrollBars메소드의 오류 영역을 보완했고, 자잘한 버그들을 찾아서 조치했다.

이 부분은 직접 소스를 참조하도록 하자. 

 

WANI Grid_20191009.zip
0.55MB

 

 

 

 

 

반응형

+ Recent posts