반응형

Grid Header 영역 클릭 시 컬럼 선택을 표현하기 위해 배경 색상을 바꾸어 보았다. 마찬가지로 좌측 첫 열의 빈 공간을 클릭하면 행(Row)이 선택되도록 할 것이다.

기존의 컬럼 선택과 큰 차이가 없지만 행(Row) 선택을 표현하기 위한 코드를 같이 살펴보기로 하자.

[그림 12-1] 행 선택 영역

먼저 WANIGrid.cs 파일에 선택된 행(Row) 정보를 관리하기 위한 변수를 추가한다.

 

private List<int> selectedRows = new List<int>();   //선택된 행(Rows)들을 관리하기 위한 변수

 

마우스 다운 이벤트에 마우스 좌측 버튼이 눌러졌을 경우에 Top Header 영역이 아닌 상단 이미지와 같은 맨 좌측 영역에서 클릭 이벤트가 발생했을 경우, 선택된 행(Row)의 색상은 변경하도록 한다.

private void WANIGrid_MouseDown(object sender, MouseEventArgs e)
{
    //마우스 우측 버튼 클릭 시 Context 메뉴 제공
    if (e.Button == MouseButtons.Right)
    {
        //Grid Header 영역이 선택되어졌을 경우에는 메뉴 제공하지 않음.
        if (e.Y < grid.TopHeaderHeight) return;
        //마우스 우측 버튼이 클릭된 좌표 값을 얻어온다.
        Point p = new Point(e.X, e.Y);

        rightClickMenu.Show(this, p);
    }
    else if (e.Button == MouseButtons.Left)
    {
        //WANIGrid Top Header 영역을 마우스 좌측 버튼으로 클릭했을 때
        if (e.Y < topHeaderHeight)
        {
            MouseLeftButtonClickInTopHeadHeight(sender, e);
        }
        else //WANIGrid의 Top Header 영역을 제외한 영역에서 마우스 좌측 버튼을 클릭했을 때
        {
            MouseLeftButtonClickInContents(sender, e); --> 추가한 영역
        }
    }
}

 

마우스 좌측 버튼을 WANIGrid Control의 Header영역에서 클릭했을 때 호출되는 메소드인 MouseLeftButtonClickInToHeaderHeight에 시프트 키가 눌러졌을 때의 동작을 추가한 소스는 아래와 같다.

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이면 처리하지 않음

        //Control Key를 누르지 않은 상태에서 컬럼을 선택했을 경우
        if (Control.ModifierKeys != Keys.Control && Control.ModifierKeys != Keys.Shift)
        {
            //선택된 컬럼일 경우
            if (selectedCols.Contains(col))
            {
                if (selectedCols.Count > 1) //선택된 컬럼이 두 개 이상일 경우
                {
                    selectedCols.Clear(); //여러 컬럼이 선택된 경우 기존의 선택된 컬럼 무효화
                    selectedCols.Add(col); //선택 컬럼 추가
                }
                else selectedCols.Remove(col);  //동일한 컬럼을 2번 선택하면 선택 표시 지움
            }
            else //선택된 컬럼이 없을 경우 기존 선택 컬럼을 모두 지우고 선택한 컬럼을 추가
            {
                selectedCols.Clear();
                selectedCols.Add(col);
            }
        }
        else
        {
            if (Control.ModifierKeys == Keys.Shift && selectedCols.Count > 0)
            {
                int index = selectedCols[0];
                int begin = Math.Min(col, index);
                int end = Math.Max(col, index);
                selectedCols.Clear();
                for (int i = begin; i <= end; i++)
                {
                    selectedCols.Add(i);
                }
            }
            else if (Control.ModifierKeys == Keys.Control)
            {
                if (selectedCols.Contains(col)) selectedCols.Remove(col);   //선택된 컬럼을 다시 선택할 경우 제거해서 컬럼 선택 무효화
                else selectedCols.Add(col); //선택된 컬럼을 추가
            }
        }
        Invalidate();
    }
    mousePoint.X = e.X;
    mousePoint.Y = e.Y;
}

 

마우스 좌측 버튼을 WANIGrid Control의 맨 왼쪽 부분에서 클릭했을 때 호출되는 메소드는 아래와 같다.

private void MouseLeftButtonClickInContents(object sender, MouseEventArgs e)
{
    selectedCols.Clear();
    int row = GetRowFromY(e.Y);
    if (row < 0) return;    //row값이 -1이면 처리하지 않음
    if (e.X < leftHeaderWidth)  //맨 좌측의 첫 컬럼을 선택했을 시 Row를 선택하도록 처리
    {
        if (Control.ModifierKeys != Keys.Control && Control.ModifierKeys != Keys.Shift)
        {
            if (selectedRows.Contains(row))
            {
                if (selectedRows.Count > 1) //선택된 행(Row)이 2개 이상일 경우
                {
                    selectedRows.Clear();   //여러 행(Row)가 선택된 경우 기존의 선택된 행(Row) 무효화
                    selectedRows.Add(row);  //선택 행(Row) 추가
                }
                else selectedRows.Remove(row);  //동일한 행(Row)를 2번 선택하면 선택 표시 지움
            }
            else //선택된 행(Row)가 없을 경우 기존 선택 행(Row)를 모두 지우고 선택한 행(Row)를 추가
            {
               selectedRows.Clear();
               selectedRows.Add(row);
            }
        }
        else
        {

            //Shift 키를 누르고 선택된 행이 1개 이상일 경우

            if (Control.ModifierKeys == Keys.Shift && selectedRows.Count > 0)

            {

                int index = selectedRows[0]; 
                int begin = Math.Min(row, index);  
                int end = Math.Max(row, index);
                selectedRows.Clear();
                for (int i = begin; i <= end; i++)
                {
                    selectedRows.Add(i);
                }

            }            
            else if (Control.ModifierKeys == Keys.Control) //컨트롤 키를 누른 상태일 경우

            {

                //선택된 행(Row)을 다시 선택할 경우 제거해서 행(Row) 선택 무효화

                if (selectedRows.Contains(row)) selectedRows.Remove(row);    
                else selectedRows.Add(row); //선택된 행(Row)를 추가

            }
        }
    }
    else
    {
        selectedRows.Clear();
    }

    Invalidate();
}

 

지금까지는 마우스의 좌측 버튼 클릭 시의 위치를 계산해서 선택된 행(Row)을 확인하고 선택 행(Row) 정보를 관리하는 selectedRows 변수에 값을 할당하거나 제거하는 로직을 작성했다.

컨트롤 키와 쉬프트 키가 눌러졌을 때, 행 선택 방법도 정의를 했다. 컨트롤 키를 누른 상태에서 행이나 컬럼을 선택했을 경우에는 여러 행과 컬럼이 선택되도록 했고, 시프트 키를 눌렀을 때에는 시작 행/컬럼 부터 다음 선택 행/컬럼 사이의 모든 행/컬럼이 선택되도록 했다.

실제 선택된 행(Row)의 바탕색을 변경하기 위한 데이터 작업은 완료했으나, 아직은 WANIGrid Control에서는 색상이 변경되는 모습은 볼 수 없다.

실제 선택된 행(Row)의 값이 변경된 후에 Invalidate() 메소드 호출이 되는 순간 WANIGrid Control의 Display 영역을 새롭게 그리기된다.

Control 영역을 다시 그릴 때 선택된 행(Row)의 배경 색이 나타날 수 있도록 해야 한다.

이렇게 하기 위해서는 WANIGrid Control의 배경을 담당하고 있는 DrawBackground 메소드에 선택된 행(Row)의 백그라운드를 그리는 로직을 추가한다.

private void DrawBackground(Graphics g, Rectangle rc) 

{

    .....

    //선택된 행(Row)의 Background를 그린다.
    for (int i = 0; i < selectedRows.Count; i++)
    {
        int index = selectedRows[i];                
        int top = topHeaderHeight;

        int width = 0;

        for (int k = firstVisibleCol; k <= lastVisibleCol; k++)
        {
            if (grid.GridHeaderList[k].Visible) width += grid.GridHeaderList[k].Width;
        }

        for (int j = firstVisibleRow; j < lastVisibleRow && j < index; j++)
        {
            top += rows[j].MaxLines * rowHeight;
        }

        //선택된 행(Row) 영역의 배경색을 표현한다.
        g.FillRectangle(selectedColor, leftHeaderWidth + 1, top + 1, width, rowHeight); 
    }

}

 

이렇게 함으로써 행(Row)를 선택하면 선택된 행(Row)의 배경색이 변경되어 선택된 행(Row)임을 사용자에게 표현해서 보여 줄 수 있게 되었다.

[그림 12-2] 한 개 행(Row) 선택
[그림 12-3] 여러 행(Row) 선택

아직도 가야 할 길이 멀기는 하지만 필요한 기능들을 하나 씩 만들어 가보기로 하자.

저자 또한 필요한 기능들을 직접 학습과 개발/테스트를 통해서 완성해 가고 있는 부분이기도 하다. 이러한 이유로 진도가 좀 더뎌지는 이유이기도 하다.

지금 까지의 소스는 아래의 파일을 참조하자.

WANI Grid_20190728.zip
0.35MB

반응형

+ Recent posts