반응형

WANIGrid Control의 겉 모습을 어느 정도 구현을 했다. 행(Row) 추가 기능을 통해서 새로운 행들을 생성하고 가로/세로 스크롤바로 WANIGrid Control 내의 모습을 볼 수 있었다. 또한 마우스 휠을 이용해서 가로/세로 스크롤바를 움직인 것과 동일한 효과도 주었다.

 

여기에 추가로 Grid의 Top Header 영역을 클릭하면 해당 컬럼의 전체 로우를 선택했음을 표현할 수 있도록 색상을 변경하는 기능을 추가해 보기로 하자.

이번 시간에는 Grid의 Top Header 영역에서 마우스 좌측 버튼을 누르면 해당 위치의 컬럼을 선택한 것으로 표시하는 기능 개발하고자 한다.

 

WANIGrid.cs 파일을 열어서 선택한 컬럼이 한 개일 수도 있지만 2개 이상의 컬럼을 선택할 수도 있다. Control Key를 누르고 마우스 좌측 버튼을 눌렀을 경우에는 1개 이상의 컬럼을 선택할 수 있도록 처리할 것이다.

마우스 좌측 버튼만 눌렀을 때에는 한 개의 컬럼만 선택될 수 있도록 처리하도록 한다.

WANIGrid Header 영역의 맨 왼쪽 컬럼을 선택했을 경우는 아무런 처리가 되지 않도록 한다. 향 후에 이 영역을 선택했을 경우 모든 영역을 선택하도록 할 수도 있겠지만 지금은 아무런 동작을 하지 않도록 한다.

 

선택된 컬럼의 Index정보를 관리하기 위한 변수, 선택된 영역의 색상을 지정할 수 있도록 지원하기 위한 변수와 현재 마우스의 좌측 버튼 클릭 시 X, Y 좌표를 저장하기 위한 변수를 선언하도록 한다.

 

private List<int> selectedCols = new List<int>();   //선택된 컬럼(Columns)들을 관리하기 위한 변수

private Point mousePoint = new Point(0, 0); //Click한 마우스 좌표를 저장하기 위한 변수
private SolidBrush selectedColor = new SolidBrush(Color.LightCyan);

 

선택된 영역의 색상은 변경하기 위한 Property를 아래와 같이 설정한다. 디폴트 색상이 아닌 다른 색상을 지정하고자 할 경우 아래의 Property를 이용해서 색상을 변경할 수 있다.

 

public Color SelectedColor
{            
    set { selectedColor = new SolidBrush(value); }
}

 

실제 마우스 좌측 버튼이 클릭 되었을 때 마우스 X좌표의 위치로 컬럼의 Index정보를 반환하는 메소드는 아래와 같다.

 

private int GetColFromX(int X)
{
    int col = 0;
    int tempWidth = leftHeaderWidth; //맨 첫번째 비어 있는 컬럼의 폭

    if (X >= 0 && X <= leftHeaderWidth) //마우스 좌측 버튼 클릭 시 X좌표가 leftHeaderWidth 영역 내에 있을 경우에는 col변수에 -1값을 설정
    {
        col = -1;
    }
    else
    {

        //마우스 좌측 버튼 클릭 시 X좌표의 위치가 현재 보여지는 컬럼 내의 위치에 해당하는지 체크
        for (col = firstVisibleCol; col < lastVisibleCol; col++)
        {
            int width = grid.GridHeaderList[col].Width;
            if (X < width + tempWidth) break; //X좌표 위치와 컬럼 Index가 매핑 되었을 경우
            tempWidth += width;
        }
    }
    if (col > grid.GridHeaderList.Count - 1) col = -1; //매핑된 컬럼 Index값이 실제 컬럼 개수보다 많을 경우 -1을 반환
    return col;

}

 

마우스 좌측 버튼 클릭 시 X좌표에 해당하는 컬럼 Index를 가져오는 메소드까지 만들었다.

이제는 마우스 버튼이 눌러졌을 때 발생하는 이벤트에 마우스 좌측 버튼 클릭 부분을 추가하기로 하자.

MouseDown 이벤트 처리 부분을 살펴보자.

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

 

실제 WANIGrid Top Header 영역이 클릭 되었을 때 호출되는 MouseLeftButtonClickInTopHeaderHeight 메소드는 아래와 같다.

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 (ModifierKeys != Keys.Control)
            {
                //선택된 컬럼일 경우
                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 (selectedCols.Contains(col)) selectedCols.Remove(col);   //선택된 컬럼을 다시 선택할 경우 제거해서 컬럼 선택 무효화
                    else selectedCols.Add(col); //선택된 컬럼을 추가
        }
        Invalidate();
    }

    //마우스 좌측 버튼 클릭 시 X/Y좌표를 저장
    mousePoint.X = e.X;
    mousePoint.Y = e.Y;
}

 

지금까지는 마우스 좌측 버튼 클릭 시 마우스 X좌표 위치에 대응하는 컬럼의 Inxex 값을 찾기 위한 로직을 만들었고, 실제 사용자에게 선택된 컬럼을 색상으로 보여주는 부분을 추가해야 실제 WANIGrid Control 실행 시에 사용자와 직접 상호작용하면서 선택된 컬럼 영역을 다이나믹하게 보여주게 된다.

 

기존의 DrawBackground 메소드에 선택된 컬럼의 배경 색상을 변경하는 기능을 아래와 같이 추가해야 한다.

 

    //선택된 컬럼의 Background를 그린다.
    for (int i = 0; i < selectedCols.Count; i++)   //선택된 컬럼의 갯수 만큼 반복
    {
        int index = selectedCols[i];
        int left = leftHeaderWidth;

        //WANIGrid Control 영역에서 보여지고 있는 컬럼 내에서 선택된 컬럼의 폭을 구한다.
        for (int j = firstVisibleCol; j < lastVisibleCol && j < index; j++)
        {
            left += grid.GridHeaderList[j].Width;
        }

        if (allRowsHeight > 0) //추가된 행(Row)가 있을 경우에만 처리
        {             
            g.FillRectangle(selectedColor, left + 1, topHeaderHeight, grid.GridHeaderList[index].Width + 1, 

                                 allRowsHeight - (rowHeight * firstVisibleRow) + 1);
        }
    }

 

이렇게 구현한 WANIGrid Control이 실행되었을 때 화면이다.

[그림 11-1] 1개의 컬럼을 선택했을 경우
[그림 11-2] 컨트롤 키를 누른 상태에서 여러 컬럼을 선택했을 경우

WANIGrid Control의 모습이 전보다는 좀 더 진화된 상태가 되었다.

다음에는 Row 선택 기능을 추가해 보기로 하자. 

 

지금까지의 소스는 아래를 참고하면 된다.

WANI Grid_20190725.zip
0.35MB

반응형

+ Recent posts