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

[C#] ListView Column Header에 체크박스 삽입

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

구글링을 해본 결과 3가지 정도의 방법으로 갈리는데, 그 중 가장 정상적으로 동작하고 깔끔한 방법이다.

 

Owner draw를 이용하여 컬럼 헤더에 체크박스를 삽입하고, 클릭 이벤트에서 컨트롤 하는 방법이다.

 

타 언어를 찾아보니 체크박스를 강제로 삽입해서 그려주던데 c#은 체크박스렌더러가 따로있다. 윈도우API의 위엄 ㄷㄷㄷ

 

아주 잘 동작한다. c#은 윈도우 API 보는 재미가 쏠쏠한듯...

 

 

1. 컬럼 헤더 0열에 체크박스용 더미를 만든다. 텍스트는 ""로 하면 된다. 너비는 25정도가 무난하다.

2. 속성에서 CheckBoxes와 OwnerDraw를 True로 변경한다.

3. 다음의 이벤트를 등록한다.

  - DrawColumnHeader

  - DrawItem

  - DrawSubItem

 

이벤트를 줄줄이 등록하는 이유는 다른 관련 이벤트가 발생 시, 렌더링이 변경되면 안되기 때문에 디폴트로 등록하기 위해서이다.

 

private void listView1_DrawColumnHeader(object sender, DrawListViewColumnHeaderEventArgs e)
{
	if (e.ColumnIndex == 0)
	{
		e.DrawBackground();
		bool value = false;

		try
		{
			value = Convert.ToBoolean(e.Header.Tag);
		} catch (Exception)
		{
		}

		CheckBoxRenderer.DrawCheckBox(e.Graphics, 
			new Point(e.Bounds.Left + 4, e.Bounds.Top + 4), 
			value ? System.Windows.Forms.VisualStyles.CheckBoxState.CheckedNormal : System.Windows.Forms.VisualStyles.CheckBoxState.UncheckedNormal);
	} else {
		e.DrawDefault = true;
	}                
}

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_ColumnClick(object sender, ColumnClickEventArgs e)
{
	if (e.Column == 0)
	{
		bool value = false;

		try
		{
			value = Convert.ToBoolean(this.listView1.Columns[e.Column].Tag);
		} catch (Exception)
		{
		}

		this.listView1.Columns[e.Column].Tag = !value;
		foreach (ListViewItem item in this.listView1.Items)
			item.Checked = !value;

		this.listView1.Invalidate();
	}            
}




출처: https://crazylobelia.tistory.com/29 [CrazyLobelia]