본문 바로가기
개발언어/C#

[C#] ListView의 체크박스(CheckBox) 추가하는 방법

by 창용이랑 2021. 8. 10.
728x90

C# 에서 칼럼의 첫번째에 체크박스를 그리는 방법이다.

 

 

 

 

먼저 listView 열편집(ColumnHeader 컬렉션 편집기)을 아래와 같이 첫번째 칼럼에는 텍스트는 빈공백으로 준다.열너비는 30이나 25 정도로 주면 된다.

소스코드에 직접 적어주려면 listView1.Columns[0].Width = 25;

 

 

 

 

DB에서 가져온 정보를 listView 화면에 출력할 때 아래와 같이 처리를 해준다.

listView1.Items.Clear();
if (R.HasRows)
{
    int i = 0;
    while (R.Read())
    {
        i = i + 1;
        ListViewItem lvt = new ListViewItem();
        //lvt.Text = i.ToString();  // 첫번째 열은 값을 넣지 않는다. checkbox 용도
        lvt.SubItems.Add(i.ToString());
        lvt.SubItems.Add(R["uid"].ToString());
        lvt.SubItems.Add(R.GetString(1));
        lvt.SubItems.Add(R.GetString(2));
        lvt.SubItems.Add(R.GetString(3));
        lvt.SubItems.Add(R.GetString(4));
        listView1.Items.Add(lvt);
    }
    lvt1totalcnt.Text = "총 " + i.ToString() + " Row";
}

 

      다.

참고한 사이트

http://stackoverflow.com/questions/1778600/listview-header-check-box

http://egloos.zum.com/seraph4021/v/4798702

 

listView_Table 정보를 출력하는 함수에

listView1.CheckBoxes = true;
listview.OwnerDraw = true;

  다.

 

또는 속성창에서 아래처럼 추가를 해준다.

 

 

 

 

 

 

 

 Event를 추가한다.

 

 

 

 

이제 코드를 추가해준다.

private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
    if ((e.ColumnIndex == 0))
    {
        CheckBox cck = new CheckBox();
        Text = "";       
        listView1.SuspendLayout();  // 컨트롤의 레이아웃 논리를 임시로 일시 중단
        e.DrawBackground();  // 열 머리글의 배경색을 그리기
        cck.BackColor = Color.Transparent;
        cck.UseVisualStyleBackColor = true;  // 비주얼 스타일을 사용하여 배경을 그리면 true

        // 컨트롤의 범위를 지정된 위치와 크기로 설정 (Left x, Top y, width, height)
        cck.SetBounds(e.Bounds.X, e.Bounds.Y, cck.GetPreferredSize(new Size(e.Bounds.Width, e.Bounds.Height)).Width, cck.GetPreferredSize(new Size(e.Bounds.Width, e.Bounds.Height)).Width);

       // 컨트롤의 높이와 너비를 가져오거나 설정

        cck.Size = new Size((cck.GetPreferredSize(new Size((e.Bounds.Width - 1), e.Bounds.Height)).Width + 1), e.Bounds.Height);
        cck.Location = new Point(4, 0); // 왼쪽 위를 기준으로 컨트롤의 왼쪽 위의 좌표를 가져오거나 설정
        listView1.Controls.Add(cck);
        cck.Show();
        //cck.BringToFront();
        Visible = true;  // 컨트롤과 모든 해당 자식 컨트롤이 표시되면 true

        e.DrawText((TextFormatFlags.VerticalCenter | TextFormatFlags.Left));
        cck.Click += new EventHandler(Bink);  // 컨트롤을 클릭하면 발생
        listView1.ResumeLayout(true);  // 일반 레이아웃 논리를 다시 시작

    }
    else
    {
        e.DrawDefault = true;
    }
}

// 컬럼헤더에 있는 체크박스 클릭시 나머지 체크박스들도 자동 체크되도록 하는 로직
private void Bink(object sender, System.EventArgs e)
{
    CheckBox cck = sender as CheckBox;
    for (int i = 0; i < listView1.Items.Count; i++)
    {
        listView1.Items[i].Checked = cck.Checked;
    }
}

private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
    e.DrawDefault = true;
}       

private void listView1_DrawSubItem(object sender, DrawListViewSubItemEventArgs e)
{
    e.DrawDefault = true;
}

 

이렇게 하면 체크박스는 추가가 된다.

private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
로직에 문제가 있는지 몰라도 두개의 행을 선택하려고 Shift 또는 Ctrl 키를 누르면 화면이 이상해진다.
테스트 해보니까 이 부분 처리가 완벽하지 않는가 보다.

 

cck.BringToFront(); 부분을 주석처리하니까 이런 현상이 없어졌다.

    다.

// 체크박스가 선택되어 있으면 삭제되는 함수

private void DeleteLineChecked_listView(ListView LV)
{
    for (int row = LV.Items.Count - 1; row >= 0; row--)
    {
        if (LV.Items[row].Checked)
        {
            //LV.Items.Remove(LV.Items[row]);
            LV.Items.RemoveAt(row);
        }
    }
    listView_No(LV);  // 번호 다시 매기기
}



//체크된 항목의 갯수는 listView1.CheckedItems.Count

while (LV.CheckedItems.Count > 0)
{
    ListViewItem row = LV.CheckedItems[0]; // 체크된 것 하나씩 지우면 첫번째 것이 된다
    LV.Items.Remove(row);
}



//체크된 Line 을 다른 listView 로 복사하는 방법

private void CheckedLineCopyTo_listView(ListView LV1, ListView LV2)
{
    for (int row = LV1.Items.Count - 1; row >= 0; row--)  // 총 Line 수만큼 반복
    {
        if (LV1.Items[row].Checked)  // 체크된 항목이 있는 경우
        {
            LV2.Items[row].SubItems[3].Text = LV1.Items[row].SubItems[3].Text;  // listView1 에서 listView2 로 복사
        }
    }
    LV2.Update();  // listView2 업데이트
}



출처: https://link2me.tistory.com/820 [소소한 일상 및 업무TIP 다루기]