안녕하세요. 윈도우 폼에서 폴더를 선택했을 때 파일 목록을 가져오는 방법에 대해 알아보겠습니다.
우선 프로그래밍을 하기 전에 어떤 내용을 만들지 정리해 볼께요.
1. 윈도우 폼에 하위폴더 포함 여부를 선택할 수 있는 체크박스를 추가한다
2. 버튼을 추가하여 버튼을 클릭하면 폴더를 선택할 수 있는 창이 나타나도록 설정한다.
3. 폴더 선택을 완료하면 하위폴더 포함 여부에 따라 파일 리스트를 출력한다.
그럼 위 내용대로 진행해 보겠습니다.
1. Visual Studio(2017 기준) 를 실행하고 새로운 프로젝트를 생성합니다.
상단 메뉴의 파일(F) - 새로 만들기(N) - 프로젝트(P) 를 선택합니다.
좌측 메뉴에 Visual C# - Windows 클래식 바탕화면을 선택하고 가운데 메뉴에 Windows Forms 앱(,net Framework)를 선택합니다.
앱 이름은 WindowsFormsFileList 로 정하겠습니다. 폴더는 원하는 위치를 지정해 주세요. 아래 그림과 같이 설정이 끝났으면 확인 버튼을 클릭합니다.
그러면 다음과 같은 화면이 나타납니다.(Visual Studio 설정여부에 따라 화면이 다르게 나타납니다.)
폼 이름 및 크기를 바꿔볼께요.
폼을 선택하고 속성 도구를 열고 Text와 Size 속성을 바꿉니다.
(Name): Form1 - Text: 선택 폴더의 파일 목록 가져오기 / Size: 800, 600
다음에 컨트톨을 추가해 보겠습니다.
도구 상자탭을 선택하고 원하는 도구 상자를 드래그해서 폼 안에 넣으면 됩니다.
저는 아래와 같이 넣었습니다.
각 도구의 주요 속성은 다음과 같습니다.
버튼(Button) - (Name): button1 / Location: 20, 20 / AutoSize: False / Size: 70, 20 / Text: 폴더 선택
확인상자(CheckBox) - (Name): checkBox1 / Location: 100, 22 / AutoSize: True / Size: 104, 16(자동으로 설정됨) / Text: 하위 폴더 포함
라벨(Label) - (Name): label1 / Location: 20, 50 / AutoSize: True / Size: 73, 12(자동으로 설정됨) / Text: 선택된 폴더:
라벨(Label) - (Name): label2 / Location: 100, 50 / AutoSize: True / Size: 29, 12(자동으로 설정됨) / Text: 없음
자료보기창(DataGridView) - (Name): dataGridView1 / Location: 20, 80 / AutoSize: False / Size: 750, 460
외형을 완성했으면 이제 프로그래밍을 해보겠습니다.
폴더 선택 버튼을 더블클릭하면 아래 그림과 같이 자동으로 이벤트가 추가되고 코드보기 화면으로 전환됩니다.
버튼 클릭 이벤트에 추가하기 전에 필요한 함수를 미리 만들어 보겠습니다.
시작하기 전에... 아래 코드를 작성하기 위해서 아래 클래스를 추가로 불러와야 합니다.
using System.IO;
using Microsoft.WindowsAPICodePack.Dialogs;
using Microsoft.WindowsAPICodePack.Dialogs; 을 불러오는 방법은 아래 글을 참고해 주세요.
글 제목: FolderBrowserDialog 보다 괜찮은 폴더 선택 화면 - CommonOpenFileDialog
링크: http://ilbbang.tistory.com/22
매서드1: 선택한 목록의 파일 및 정보를 DataTable 형식으로 보낼 수 있는 매서드를 아래와 같이 추가합니다.
/// <summary>
/// 선택한 폴더의 파일 목록을 DataTable형식으로 내보냅니다.
/// </summary>
/// <param name="FolderName">선택한 폴더의 전체 경로를 입력합니다.</param>
/// <returns></returns>
private DataTable GetFileListFromFolderPath(string FolderName)
{
DirectoryInfo di = new DirectoryInfo(FolderName); // 해당 폴더 정보를 가져옵니다.
DataTable dt1 = new DataTable(); // 새로운 테이블 작성합니다.(FileInfo 에서 가져오기 원하는 속성을 열로 추가합니다.)
dt1.Columns.Add("Folder", typeof(string)); // 파일의 폴더
dt1.Columns.Add("FileName", typeof(string)); // 파일 이름(확장자 포함)
dt1.Columns.Add("Extension", typeof(string)); // 확장자
dt1.Columns.Add("CreationTime", typeof(DateTime)); // 생성 일자
dt1.Columns.Add("LastWriteTime", typeof(DateTime)); // 마지막 수정 일자
dt1.Columns.Add("LastAccessTime", typeof(DateTime)); // 마지막 접근 일자
foreach (FileInfo File in di.GetFiles()) // 선택 폴더의 파일 목록을 스캔합니다.
{
dt1.Rows.Add(File.DirectoryName, File.Name, File.Extension, File.CreationTime, File.LastWriteTime, File.LastAccessTime); // 개별 파일 별로 정보를 추가합니다.
}
if(checkBox1.Checked == true) // 하위 폴더 포함될 경우
{
DirectoryInfo[] di_sub = di.GetDirectories(); // 하위 폴더 목록들의 정보 가져옵니다.
foreach (DirectoryInfo di1 in di_sub) // 하위 폴더목록을 스캔합니다.
{
foreach (FileInfo File in di1.GetFiles()) // 선택 폴더의 파일 목록을 스캔합니다.
{
dt1.Rows.Add(File.DirectoryName, File.Name, File.Extension, File.CreationTime, File.LastWriteTime, File.LastAccessTime); // 개별 파일 별로 정보를 추가합니다.
}
}
}
return dt1;
}
FileInfo 클래스에서 가져올 수 있는 속성은 아래 링크를 확인해 주세요.
https://msdn.microsoft.com/ko-kr/library/system.io.fileinfo(v=vs.110).aspx
매서드2: 위의 결과를 컨트롤에 보여줄 수 있는 매서드를 아래와 같이 추가합니다.
/// <summary>
/// 선택한 폴더의 파일 목록을 가져와서 DataGridView 도구에 보여줍니다.
/// </summary>
/// <param name="dt1">선택한 폴더의 파일 목록이 들어있는 DataTable을 입력합니다.</param>
/// <param name="dgv1">결과를 출력할 DataGridView를 선택합니다.</param>
private void ShowDataFromDataTableToDataGridView(DataTable dt1, DataGridView dgv1)
{
dgv1.Rows.Clear(); // 이전 정보가 있을 경우, 모든 행을 삭제합니다.
dgv1.Columns.Clear(); // 이전 정보가 있을 경우, 모든 열을 삭제합니다.
foreach (DataColumn dc1 in dt1.Columns) // 선택한 파일 목록이 들어있는 DataTable의 모든 열을 스캔합니다.
{
dgv1.Columns.Add(dc1.ColumnName, dc1.ColumnName); // 출력할 DataGridView에 열을 추가합니다.
}
int row_index = 0; // 행 인덱스 번호(초기 값)
foreach(DataRow dr1 in dt1.Rows) // 선택한 파일 목록이 들어있는 DataTable의 모든 행을 스캔합니다.
{
dgv1.Rows.Add(); // 빈 행을 하나 추가합니다.
foreach (DataColumn dc1 in dt1.Columns) // 선택한 파일 목록이 들어있는 DataTable의 모든 열을 스캔합니다.
{
dgv1.Rows[row_index].Cells[dc1.ColumnName].Value = dr1[dc1.ColumnName]; // 선택 행 별로, 스캔하는 열에 해당하는 셀 값을 입력합니다.
}
row_index++; // 다음 행 인덱스를 선택하기 위해 1을 더해줍니다.
}
foreach(DataGridViewColumn drvc1 in dgv1.Columns) // 결과를 출력할 DataGridView의 모든 열을 스캔합니다.
{
drvc1.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells; // 선택 열의 너비를 자동으로 설정합니다.
}
}
위 두개의 매서드가 포함된 버튼 클릭 이벤트를 다음과 같이 추가합니다.
private void button1_Click(object sender, EventArgs e)
{
CommonOpenFileDialog dialog = new CommonOpenFileDialog(); // 새로운 폴더 선택 Dialog 를 생성합니다.
dialog.IsFolderPicker = true; //
if (dialog.ShowDialog() == CommonFileDialogResult.Ok) // 폴더 선택이 정상적으로 되면 아래 코드를 실행합니다.
{
label2.Text = dialog.FileName; // 선택한 폴더 이름을 label2에 출력합니다.
DataTable dt_filelistinfo = GetFileListFromFolderPath(dialog.FileName);
ShowDataFromDataTableToDataGridView(dt_filelistinfo, dataGridView1);
}
}
전체 코드가 포함된 화면은 다음과 같습니다.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.WindowsAPICodePack.Dialogs;
using System.IO;
namespace WindowsFormsFileList
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
CommonOpenFileDialog dialog = new CommonOpenFileDialog(); // 새로운 폴더 선택 Dialog 를 생성합니다.
dialog.IsFolderPicker = true; //
if (dialog.ShowDialog() == CommonFileDialogResult.Ok) // 폴더 선택이 정상적으로 되면 아래 코드를 실행합니다.
{
label2.Text = dialog.FileName; // 선택한 폴더 이름을 label2에 출력합니다.
DataTable dt_filelistinfo = GetFileListFromFolderPath(dialog.FileName);
ShowDataFromDataTableToDataGridView(dt_filelistinfo, dataGridView1);
}
}
private DataTable GetFileListFromFolderPath(string FolderName)
{
생략(매서드1)
}
private void ShowDataFromDataTableToDataGridView(DataTable dt1, DataGridView dgv1)
{
생략(매서드2)
}
}
}
실행하면 다음과 같이 나타납니다.
우선 하위 폴더 포함이 안되어 있을 경우에는 아래 그림과 같이 결과가 출력됩니다.
파위폴더 포함된 경우에는 아래 그림과 같이 결과가 출력됩니다.
감사합니다.