반응형

지금까지의 작업으로 WANIGrid의 겉모습을 어느 정도 완성을 했다.

WANIGridTest 프로젝트의 WinForm인 WANIGridTest.cs에서 WANIGrid를 구성하는 기본 정보들을 셋팅해서 WANIGrid의 내용을 그려주고 직접 값을 입력/수정 및 행 추가/삭제 등의 작업을 진행할 수 있게 되었다.

그러나 WANIGridTest 프로젝트 내의 WinForm파일 인 WANIGridTest.cs 파일을 더블 클릭해서 디자인 화면을 열어보면 아래와 같은 오류 메시지가 나타나며 보기에 영 꺼림칙한 모습이다.

[그림 20-1] WinForm에 포함된 WANIGrid Control에서 발생한 오류

위 오류 메시지를 자세히 보면 WANIGrid의 외형을 그리는 메소드 중 DrawBackground 메소드에서 개체가 생성되지 않아서 발생하는 오류임을 알 수 있다.

이 오류를 없애기 위해서는 메시지를 확인하고 해당 파일의 오류 부분을 소스에서 찾아서 확인을 해야한다.

 

WANIGrid.Method.cs 파일 내의 273행에서 오류가 발생했으며, GetLastFixedCol() 메소드를 호출하면서 "개체 참조가 개체의 인스턴스로 설정되지 않았습니다"라는 오류 메세지를 내뱉게 된 것이다.

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


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

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

 

여기서 호출하는 GetLastFixedCol 메소드를 먼저 손보기로 하자.

Header 정보가 없을 경우에는 -1 값을 리턴하도록 아래의 파란색 부분을 추가한다.

    private int GetLastFixedCol()
    {
        if (grid.GridHeaderList == null) return -1;
        int lastFixedCol = 0;
        int startIndex = 0;
        foreach (Header head in grid.GridHeaderList)
        {
            if (startIndex == colFixed) break;
            if (head.Visible)
            {
                lastFixedCol = head.Index;
                startIndex++;                    
            }                                               
        }
        return lastFixedCol;
    }

 

그리고 위의 DrawBackground 메소드에서 파란색으로 표기된 부분의 코드는 WANIGrid Header영역이 정의되지 않았을 경우 즉 WinForm 디자인 모드에서 WANIGrid를 가져다 놓았을 때 사용자에게 WANIGrid의 모습을 그려주는 메소드인 DrawDefaultWANIGridControl 메소드를 호출하고 return하는 것이다.

DrawDefaultWANIGridControl 메소드가 하는 일은 비어있는 Data Grid 형태의 모습을 그려주는 것 뿐이다.

이렇게 함으로써 WinForm 디자인 시에 WANIGrid Control의 모습을 사용자가 직접 볼 수 있게 되는 것이다.

WANIGrid Control 폭과 높이에 맞는 빈 Data Grid를 그리는 메소드를 살펴보자

    private void DrawDefaultWANIGridControl(Graphics g, Rectangle rc)
    {
        //WANIGrid Control의 폭과 높이에 해당하는 row와 column의 갯수를 구한다. (컬럼 폭은 80으로 고정)
        int cols = (rc.Width / 80) + 1;
        int rows = (rc.Height / rowHeight) + 1;

        SolidBrush brush = new SolidBrush(SystemColors.ControlLight);
        Pen pen = new Pen(Color.LightGray);

 

        //헤더의 맨 왼쪽의 고정 공간을 그리는 부분
        int columnStartX = 0;
        g.FillRectangle(brush, columnStartX + 1, 1, leftHeaderWidth, topHeaderHeight);
        g.DrawRectangle(pen, columnStartX + 1, 1, leftHeaderWidth, topHeaderHeight);

        //헤더 영역을 그린다.
        columnStartX += leftHeaderWidth;  //첫 시작컬럼의 폭을 leftHeaderWidth 만큼 설정 
        for (int i = 0; i < cols; i++)
        {                
            int headerWidth = 80;   //i 번째 컬럼의 폭을 설정                                                    

            //Grid Header를 그린다.
            DrawUtil.DrawGridHeaderRectangleAndText(g, brush, blackBrush, pen, null, headerFont, i, columnStartX, 

                                                                      headerWidth, topHeaderHeight);

            columnStartX += headerWidth;
        }
        vScrollBar.Visible = true; 

        //Body 부분을 그린다.
        for (int i = 0; i < rows; i++)
        {
            columnStartX = 0;
            g.FillRectangle(brush, columnStartX + 1, i * rowHeight, leftHeaderWidth, topHeaderHeight);
            g.DrawRectangle(pen, columnStartX + 1, i * rowHeight, leftHeaderWidth, topHeaderHeight);
            columnStartX += leftHeaderWidth;

            for (int j = 0; j < cols; j++)
            {                    
                int colWidth = 80;
                                               
                g.DrawRectangle(pen, columnStartX + 1, i * rowHeight, colWidth, rowHeight);
                Rectangle rec = new Rectangle(columnStartX + 2, (i * rowHeight) + 2, columnStartX - 2, rowHeight);                        

                columnStartX += colWidth;                    
            }
        }
        hScrollBar.Visible = true;
    }

 

더불어 SelectedColChangeBackground메소드의 오류가 발생할 수 있는 부분을 미리 처리하자.

선택된 컬럼의 Backgroun를 그리는 메소드인데 선택된 컬럼이 없을 경우에는 아무런 동작을 취하지 않도록 아래의 파란색으로 표기된 부분을 추가한다.

    private void SelectedColChangeBackground(Graphics g, int lastFixedCol)
    {
        if (selectedCols == null) return;
        //선택된 컬럼의 Background를 그린다.

         :

         :

    }

여기까지 작업을 하면 디자인 시에 아래의 모습으로 보여지게 된다.

[그림 20-2] 디자인 시 WANIGrid Control의 모습

 

WANIGrid Control를 도구 상자에 추가했을 때 아이콘 모양이 나타나도록 설정을 해보자

아미콘의 사이즈는 16X16이며, 아이콘 이미지를 WANIGrid Project의 루트에 생성한다.

WANIGrid.cs 파일을 열어서 WANIGrid 클래스 정의 상단에 아래의 내용을 추가한다.

typeof 부분의 WANIGrid는 내가 만든 User Control의 명칭인 WANIGrid, 다음은 아이콘 파일의 명칭을 추가한다.

WANIGrid.ico파일에서 확장자를 제외한 명칭만 표기하면 된다.

    [ToolboxBitmap(typeof(WANIGrid), "WANIGrid")]
    public partial class WANIGrid : UserControl
    { 

        :

        :

    }

아래의 그림에서 처럼 WANIGrid.ico파일을 선택해서 속성 정보 중 [빌드 작업] 항목의 값을 "포함 리소스"로 변경하고 저장한다.

 

이렇게 하게 되면 도구 상자에 추가한 WANIGrid Control의 아이콘이 보여지게 된다.

만약 아이콘이 아래의 그림처럼 나타나지 않는다면 WANIGrid를 선택해서 마우스 우측 버튼 클릭 후 나타나는 Context 메뉴 중 삭제를 선택해서 삭제한다.

컨트롤을 추가하고자 하는 그룹을 선택한 후 마우스 우측 버튼을 눌러서 나타나는 Context 메뉴 중 항목 선택을 선택해서 WANIGrid.dll파일을 찾아서 선택하면 된다.

[그림 20-4] WANIGrid Control 아이콘

지금까지의 소스는 아래의 파일을 다운받아서 확인하면 된다.

WANI Grid_20190907.zip
0.48MB

반응형

+ Recent posts