C# Winform - 리스트박스와 리스트뷰 사용 방법, 차이점 (ListBox VS ListView)

반응형

개요

이번 포스팅에서는 C# 윈폼(Windows Forms)에서의 리스트박스(ListBox) 컨트롤과 리스트뷰(ListView) 컨트롤에 대한 내용이다.

해당 컨트롤들을 사용한 샘플 프로젝트를 통해 알아보자.

<C# Winforms 리스트박스와 리스트뷰를 활용한 샘플 프로젝트 예시 화면>

 

당연하게도 해당 프로젝트는 윈폼(Windows Forms 앱)을 사용하였다.

<Visual Studio C# Windows Forms 프로젝트 생성 화면>

 

포스팅에서 설명하는 프로젝트는 아래의 깃허브에서 확인할 수 있다.

 

GitHub - luvris2/CSharp-Winforms-Example

Contribute to luvris2/CSharp-Winforms-Example development by creating an account on GitHub.

github.com


리스트박스와 리스트뷰 (ListBox VS ListView)

리스트 박스란? (ListBox)

항목 목록을 표시하는 컨트롤이다.

리스트 박스 컨트롤 안에 선택 가능한 옵션 리스트를 표시한다.

Items 속성 안에 항목 목록을 넣게 되며, SelectedIndex를 지정하여 초기 선택값을 설정할 수 있다.

또한, 항목이 많을 경우 스크롤을 사용하여 항목 목록을 확인할 수 있다.


리스트 뷰란? (ListView)

다섯 개의 서로 다른 보기를 사용하여 목록을 표시할 수 있는 항목의 컬렉션을 나타내는 컨트롤이다.

파일 탐색기의 디렉토리 내 파일들처럼 아이템들을 여러 목록 형태로 보여준다.

목록의 형태를 지정하는 View 속성은 Details, List, LargeIcon, SmallIcon, Tile 이 있다.

  • 아래의 예제에서는 아이콘의 이미지를 설정하는 ImageList 설정이 존재하기 때문에 List와 SmallIcon 의 뷰는 같게 보인다. 실제로는 List 뷰는 아이콘 없이 텍스트만 출력된다.
  • Tile 뷰는 Details 뷰 모드를 활용하는 개념으로, 타일로 구성된 항목에 아이콘, 세부 데이터들을 표시한다.

리스트박스와 리스트뷰의 차이 (ListBox VS ListView)

리스트박스와 리스트뷰는 항목(아이템)을 표시하고 사용자가 항목을 선택하는 컨트롤러이지만,

차이점은 항목 목록을 표시하는 항목의 열 개수이다.

  • 리스트 박스 : 단일 열 항목 표시
  • 리스트 뷰 : 다중 열 항목 표시

즉, 리스트박스는 단일 열의 항목을 표시하는 데 사용되는 컨트롤이고

리스트뷰는 테이블 형식의 다중 열의 항목을 표시하는 데  컨트롤이다.

 

일반적으로 리스트박스는 간단한 항목을 표시할 때 사용하고,

리스트뷰는 보다 다양한 데이터를 표시와 사용자 정의 기능을 필요로 할 때 사용한다.


ListBox

예시 이미지

<C# ListBox 컨트롤 사용 예시>


리스트박스 UI 정의

위의 이미지처럼 항목을 표시하고, 표시한 항목을 사용자가 선택하면 레이블이 선택한 값을 표시하도록 해보자.

샘플 예시에서는 포켓몬스터 1세대 스타팅 포켓몬으로 예를 들었다 :)

폼에 항목을 표시할 ListBox 컨트롤과 선택한 항목의 값을 확인할 수 있도록 Label을 추가한다.

<C# ListBox 샘플 UI 예시>


리스트박스 항목 추가

폼 로드 시 리스트박스에 보여질 초기 값을 설정한다.

  • 초기값은 .Items.Add 속성을 이용한다.
// 리스트박스의 값 설정
listBox1.Items.Add("꼬부기");
listBox1.Items.Add("이상해씨");
listBox1.Items.Add("파이리");

<리스트박스 항목(Items) 추가 예시>

 


리스트박스 기본 선택 인덱스 설정

리스트박스의 기본 선택값을 설정하려면 SelectedIndex 속성을 이용하면 된다.

  • 인덱스는 0부터 시작한다.
// 리스트박스의 값 설정
listBox1.Items.Add("꼬부기");
listBox1.Items.Add("이상해씨");
listBox1.Items.Add("파이리");

/// 초기 인덱스 값 설정
listBox1.SelectedIndex = 2; // 파이리 기본값으로 선택

<리스트박스 기본 선택값 설정 예시>


리스트박스의 선택한 값 확인

선택한 항목(아이템)을 하단의 레이블에 표시해보자.

  • 항목이 변경될 때마다 실행되는 리스트박의 메서드는 SelectedIndexChanged 이다.
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    lblListBox.Text = "당신이 선택한 포켓몬은 " + listBox1.Text.Trim() + "입니다.";
}

<리스트박스 선택 시 항목의 값 표시 예시>


전체 소스 코드

public Form1()
{
    InitializeComponent();

    // 폼 로드
    Form1_Load(this, EventArgs.Empty);
}

// 폼 로드 시 값 설정
private void Form1_Load(object sender, EventArgs e)
{
    // 리스트박스의 값 설정
    listBox1.Items.Add("꼬부기");
    listBox1.Items.Add("이상해씨");
    listBox1.Items.Add("파이리");

    /// 초기 인덱스 값 설정
    listBox1.SelectedIndex = 2; // 파이리 기본값으로 선택
}

// 항목 선택 시 항목 값 표시
private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    lblListBox.Text = "당신이 선택한 포켓몬은 " + listBox1.Text.Trim() + "입니다.";
}

ListView

예시 이미지

<C# ListView 컨트롤 사용 예시>


리스트뷰 UI 정의

이번엔 리스트뷰 컨트롤을 활용하여 좀 더 다양한 정보 표시와 여러가지 뷰를 활용하는 기능을 구현해보자.

여러가지 뷰는 쉽게 말해 윈도우 탐색기에서 보기에서 볼 수 있는 형태를 말한다.

(큰 아이콘, 작은 아이콘, 자세히보기 등등)

 

  1. 폼에 항목을 표시할 ListView 컨트롤과 선택한 항목의 값을 확인할 수 있도록 Label을 추가한다.
    • 항목이 선택 될 때 항목의 세부 값까지 레이블에 표시해야 한다.
  2. 폼에 뷰 형식을 바꿔서 볼 수 있도록 GroupBox 컨트롤 안에 RadioButton을 나열한다.
    • 나열되는 값은 위에서부터 차례로 큰 아이콘(LargeIcon), 작은 아이콘(SmallIcon), 리스트(List), 자세히(Details), 타일(Tile)이다.

<C# ListView 샘플 UI 예시>


리스트뷰 항목 추가

폼 로드 시 리스트박스에 보여질 초기 값을 설정한다.

포스팅에서는 포켓몬의 HP, 공격력, 방어력을 기준으로 하였다 XD

  • ListViewItem : 보여질 항목을 생성한다. 항목명 뒤에는 보여질 순서의 인덱스를 기재한다.
  • SubItems.Add : 보여질 항목의 세부 데이터를 추가한다.
  • Columns.Add : 항목의 세부 데이터를 표시하는 열의 헤더 이름을 설정한다.
  • Items.Add : 리스트 뷰에 항목을 추가한다. ListViewItem 형태로 생성된 항목을 추가해야 한다.
// 리스트뷰의 값 설정 (항목 추가)
ListViewItem item1 = new ListViewItem("꼬부기", 0);
ListViewItem item2 = new ListViewItem("이상해씨", 1);
ListViewItem item3 = new ListViewItem("파이리", 2);

// 항목의 각 열의 데이터 추가
// 꼬부기 세부 데이터
item1.SubItems.Add("44");
item1.SubItems.Add("48");
item1.SubItems.Add("65");

// 이상해씨 세부 데이터
item2.SubItems.Add("45");
item2.SubItems.Add("49");
item2.SubItems.Add("49");

// 파이리 세부 데이터
item3.SubItems.Add("39");
item3.SubItems.Add("52");
item3.SubItems.Add("43");

// 열의 헤더 이름 추가 : 컬럼명, 컬럼 사이즈 지정(생략 가능)
listView1.Columns.Add("포켓몬");
listView1.Columns.Add("HP");
listView1.Columns.Add("공격");
listView1.Columns.Add("방어");

// 리스트뷰에 항목의 데이터 추가
listView1.Items.Add(item1);
listView1.Items.Add(item2);
listView1.Items.Add(item3);
// 아래의 코드로 일괄 추가 가능
// listView1.Items.AddRange(new ListViewItem[] { item1, item2, item3 });

리스트뷰 뷰 모드 설정 및 변경

라디오 버튼으로 뷰 모드를 변경할 수 있도록 라디오 버튼이 선택되었을 경우의 기능을 구현한다.

각각의 라디오 버튼의 이름은 다음과 같다.

  • 큰 아이콘 : radioIconL
  • 작은 아이콘 : radioIconS
  • 리스트 : radioList
  • 자세히 : radioDetail
  • 타일 : radioTile

리스트뷰의 뷰 변경 방법은 View 속성의 값을 입력하면 된다.

// 뷰 모드 설정
private void radioIconL_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.LargeIcon; // 큰 아이콘으로 보기
}

private void radioIconS_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.SmallIcon; // 작은 아이콘으로 보기
}

private void radioList_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.List; // 리스트 형태로 보기
}

private void radioDetail_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.Details; // 자세히 보기
}

private void radioTile_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.Tile; // 타일 형태로 보기
}

 

보기에서의 옵션을 선택하면 설정한 뷰로 리스트뷰를 보여준다.

<C# 리스트뷰에서 자세히 보기 뷰 모드로 항목 확인 예시>


리스트뷰의 선택한 값 확인

선택한 항목(아이템)을 하단의 레이블에 표시해보자.

  • 항목이 변경될 때마다 실행되는 리스트뷰의 메서드는 SelectedIndexChanged 이다.
  • 리스트박스는 단일 항목이므로 리스트박스의 Text속성을 활용하면 되지만 리스트뷰는 항목을 직접 확인하여야 한다.
    1. 리스트뷰의 항목이 선택되었는지 확인한다.
    2. 선택된 항목의 값을 가져온다
    3. 레이블에 선택된 항목의 값을 출력한다.
// 리스트뷰 항목 선택 시 항목 값 표시
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
    // 리스트뷰에서 선택된 항목이 있는지 확인
    if (listView1.SelectedItems.Count > 0)
    {
        // 선택된 항목의 첫 번째 열(인덱스 0)의 값을 가져오기
        string selectedValue1 = listView1.SelectedItems[0].SubItems[0].Text; // 포켓몬 이름
        string selectedValue2 = listView1.SelectedItems[0].SubItems[1].Text; // HP 수치
        string selectedValue3 = listView1.SelectedItems[0].SubItems[2].Text; // 공격력 수치
        string selectedValue4 = listView1.SelectedItems[0].SubItems[3].Text; // 방어력 수치

        // 가져온 값을 출력하거나 필요한 작업 수행
        lblListView.Text = "[" + selectedValue1 + "] HP:" + selectedValue2 + ", 공격:" +selectedValue3 + ", 방어:" +selectedValue4;
    }
}

 

선택한 항목을 선택하면 레이블에 해당 항목의 세부 값을 확인할 수 있다.

<C# 리스트뷰의 항목의 세부값 확인 예시>


리스트뷰에 아이콘(그림) 넣기

리스트뷰에서는 항목의 아이콘을 넣을 수도 있다.

각 포켓몬의 이름에 맞는 이미지를 넣어보자. 이미지 참고는 포켓몬 팬덤의 이미지를 사용하였다.

이미지를 준비해준다. 포스팅에서는 프로젝트 루트 디렉토리에 위치하였다.

<C# 프로젝트 내에 아이콘으로 사용할 이미지 파일>

 

리스트뷰에 아이콘을 보이게 하려면 보여질 이미지 리스트를 생성해야한다.

포스팅에서는 이미지 파일로 구성하였으므로 Bitmap.FromFile을 이용하여 이미지 리스트를 구성하였다.

  • 큰 아이콘과 작은 아이콘에 보여질 이미지 리스트를 생성하고, 각 보여질 아이콘의 크기를 지정한다.
  • 이미지의 디렉토리는 'getParentDirectory'라는 사용자 정의 함수를 사용하였다.
    각자 환경에 따라 이미지 저장 위치가 다르므로 이 부분은 자신의 경로에 맞게 코드를 짜보도록 하자.
    깃허브에서 해당 샘플 프로젝트를 다운받은 경우에는 코드를 그대로 사용해도 된다.
// 리스트뷰의 항목에 보여질 이미지 리스트 생성
ImageList imageListLarge = new ImageList();
ImageList imageListSmall = new ImageList();

// 이미지 리스트의 이미지 설정
string curDir = getParentDirectory(); // 프로젝트 루트 디렉토리 경로
imageListLarge.Images.Add(Bitmap.FromFile(curDir + "\\꼬부기.png"));
imageListLarge.Images.Add(Bitmap.FromFile(curDir + "\\이상해씨.png"));
imageListLarge.Images.Add(Bitmap.FromFile(curDir + "\\파이리.png"));

imageListSmall.Images.Add(Bitmap.FromFile(curDir + "\\꼬부기.png"));
imageListSmall.Images.Add(Bitmap.FromFile(curDir + "\\이상해씨.png"));
imageListSmall.Images.Add(Bitmap.FromFile(curDir + "\\파이리.png"));

// 리스트뷰에 이미지 항목 추가
imageListLarge.ImageSize = new Size(64, 64); // 큰 아이콘의 크기
imageListSmall.ImageSize = new Size(32, 32); // 작은 아이콘의 크기
listView1.LargeImageList = imageListLarge;
listView1.SmallImageList = imageListSmall;



/* 이미지 디렉토리 확인하는 함수
* 포스팅에서는 프로젝트의 루트 디렉토리에 이미지를 위치하였다.
* 디버깅 시, bin\debug\에 파일이 생성되므로 상위 디렉토리를 확인하기 위해 함수를 추가하였다.
* 굳이 함수로 만든 이유는 리스트뷰와 소스코드의 혼선을 줄이기 위해서이다.
*/
// 프로젝트 디렉토리 경로 확인
private string getParentDirectory()
{
	// 현재 디렉토리 : ~\C#_ListBox_And_ListView_Example\bin\Debug\net6.0-windows
    string curDir = Directory.GetCurrentDirectory();
    DirectoryInfo parentDir = Directory.GetParent(curDir);
    curDir = parentDir.FullName;
    parentDir = Directory.GetParent(curDir);
    curDir = parentDir.FullName;
    parentDir = Directory.GetParent(curDir);
    curDir = parentDir.FullName;

	// 최종 디렉토리 : ~\C#_ListBox_And_ListView_Example
    return curDir;
}

<C# 리스트뷰의 항목에 아이콘 추가 예시 화면>


전체 소스 코드

public Form1()
{
    InitializeComponent();

    // 폼 로드
    Form1_Load(this, EventArgs.Empty);
}

// 폼 로드 시 값 설정
private void Form1_Load(object sender, EventArgs e)
{
    /* 리스트 뷰 설정 */
    // 리스트뷰의 값 설정 (항목 추가)
    ListViewItem item1 = new ListViewItem("꼬부기", 0);
    ListViewItem item2 = new ListViewItem("이상해씨", 1);
    ListViewItem item3 = new ListViewItem("파이리", 2);

    // 항목의 각 열의 데이터 추가
    item1.SubItems.Add("44");
    item1.SubItems.Add("48");
    item1.SubItems.Add("65");

    item2.SubItems.Add("45");
    item2.SubItems.Add("49");
    item2.SubItems.Add("49");

    item3.SubItems.Add("39");
    item3.SubItems.Add("52");
    item3.SubItems.Add("43");

    // 열의 헤더 이름 추가 : 컬럼명, 컬럼 사이즈 지정(생략 가능)
    listView1.Columns.Add("포켓몬");
    listView1.Columns.Add("HP");
    listView1.Columns.Add("공격");
    listView1.Columns.Add("방어");

    // 리스트뷰에 항목의 데이터 추가
    listView1.Items.Add(item1);
    listView1.Items.Add(item2);
    listView1.Items.Add(item3);
    // 아래의 코드로 일괄 추가 가능
    // listView1.Items.AddRange(new ListViewItem[] { item1, item2, item3 });



    /* 리스트뷰 아이콘 설정 */
    // 리스트뷰의 항목에 보여질 이미지 리스트 생성
    ImageList imageListLarge = new ImageList();
    ImageList imageListSmall = new ImageList();

    // 이미지 리스트의 이미지 설정
    string curDir = getParentDirectory(); // 프로젝트 루트 디렉토리 경로
    imageListLarge.Images.Add(Bitmap.FromFile(curDir + "\\꼬부기.png"));
    imageListLarge.Images.Add(Bitmap.FromFile(curDir + "\\이상해씨.png"));
    imageListLarge.Images.Add(Bitmap.FromFile(curDir + "\\파이리.png"));

    imageListSmall.Images.Add(Bitmap.FromFile(curDir + "\\꼬부기.png"));
    imageListSmall.Images.Add(Bitmap.FromFile(curDir + "\\이상해씨.png"));
    imageListSmall.Images.Add(Bitmap.FromFile(curDir + "\\파이리.png"));

    // 리스트뷰에 이미지 항목 추가
    imageListLarge.ImageSize = new Size(64, 64); // 큰 아이콘의 크기
    imageListSmall.ImageSize = new Size(32, 32); // 작은 아이콘의 크기
    listView1.LargeImageList = imageListLarge;
    listView1.SmallImageList = imageListSmall;
}

// 리스트뷰 항목 선택 시 항목 값 표시
private void listView1_SelectedIndexChanged(object sender, EventArgs e)
{
    // 리스트뷰에서 선택된 항목이 있는지 확인
    if (listView1.SelectedItems.Count > 0)
    {
        // 선택된 항목의 첫 번째 열(인덱스 0)의 값을 가져오기
        string selectedValue1 = listView1.SelectedItems[0].SubItems[0].Text;
        string selectedValue2 = listView1.SelectedItems[0].SubItems[1].Text;
        string selectedValue3 = listView1.SelectedItems[0].SubItems[2].Text;
        string selectedValue4 = listView1.SelectedItems[0].SubItems[3].Text;

        // 가져온 값을 출력하거나 필요한 작업 수행
        lblListView.Text = "[" + selectedValue1 + "] HP:" + selectedValue2 + ", 공격:" +selectedValue3 + ", 방어:" +selectedValue4;
    }
}

// 프로젝트 디렉토리 경로 확인
private string getParentDirectory()
{
    string curDir = Directory.GetCurrentDirectory();
    DirectoryInfo parentDir = Directory.GetParent(curDir);
    curDir = parentDir.FullName;
    parentDir = Directory.GetParent(curDir);
    curDir = parentDir.FullName;
    parentDir = Directory.GetParent(curDir);
    curDir = parentDir.FullName;

    return curDir;
}



// 뷰 모드 설정
private void radioIconL_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.LargeIcon;
}

private void radioIconS_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.SmallIcon;
}

private void radioList_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.List;
}

private void radioDetail_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.Details;
}

private void radioTile_CheckedChanged(object sender, EventArgs e)
{
    listView1.View = View.Tile;
}

참고

리스트박스 참고

리스트뷰 참고

아이콘 이미지 참고

반응형