본문 바로가기
카테고리 없음

네트워크 경로 접근성 해결을 위한 '탐색기 스타일' 다이얼로그 도입

by 공부봇 2026. 1. 8.
반응형

[UI/UX 개선] 네트워크 경로 접근성 해결을 위한 '탐색기 스타일' 다이얼로그 도입


도입 이유 3가지 요약

1. 네트워크(UNC) 경로 접근성 한계 극복

  • 기존 (FolderBrowserDialog): 트리(Tree) 구조로 되어 있어, \\192.168.10.5 같은 네트워크 경로를 찾아가려면 '네트워크' 아이콘부터 수동으로 클릭해 들어가야 하며 속도가 매우 느립니다.
  • 변경 (CommonOpenFileDialog): 윈도우 탐색기와 동일한 주소창이 있어, 네트워크 경로를 복사/붙여넣기 하여 즉시 이동할 수 있습니다.

2. 사용자 경험(UX) 표준화

  • 기존: 윈도우 XP 시절의 구형 UI로 인해 오퍼레이터가 이질감을 느낍니다.
  • 변경: 사용자가 평소 쓰던 '파일 열기' 창과 동일한 UI를 제공하므로, '즐겨찾기', '최근 항목' 등을 그대로 활용할 수 있어 직관적입니다.

3. 주소창 입력 지원

  • 기존: 오직 마우스 클릭으로만 폴더를 선택해야 합니다.
  • 변경: 상단 주소 표시줄에 직접 경로를 타이핑하거나 수정할 수 있어, 깊은 경로(Deep Path)로의 접근 효율이 압도적으로 높습니다.

Step 0: 사전 준비 (NuGet 설치)

먼저 패키지 관리자 콘솔에서 안정적인 1.1.1 버전을 설치했는지 확인하십시오. (8.x 버전은 4.8 환경에서 에러가 납니다.)

PowerShell
 
Install-Package WindowsAPICodePack-Shell -Version 1.1.1

Step 1: 공용 헬퍼 클래스 (The Solution)

다이얼로그 로직을 폼마다 복사/붙여넣기 하지 말고, DialogHelper라는 정적 클래스로 만들어 두면 유지보수가 쉽습니다.

파일명: Utils\DialogHelper.cs

C#
 
using System;
using System.Windows.Forms;
using Microsoft.WindowsAPICodePack.Dialogs; // NuGet 패키지 네임스페이스

namespace A2_SOP_Linescan.Utils
{
    public static class DialogHelper
    {
        /// <summary>
        /// 탐색기 스타일의 폴더 선택 다이얼로그를 엽니다.
        /// </summary>
        /// <param name="ownerHandle">부모 폼의 핸들 (this.Handle)</param>
        /// <param name="initialPath">초기 진입 경로 (없으면 바탕화면)</param>
        /// <param name="title">창 제목</param>
        /// <returns>선택된 폴더 경로 (취소 시 string.Empty 반환)</returns>
        public static string ShowFolderDialog(IntPtr ownerHandle, string initialPath = "", string title = "폴더 선택")
        {
            // 리소스 누수 방지를 위한 using 필수
            using (CommonOpenFileDialog dialog = new CommonOpenFileDialog())
            {
                // [핵심 1] 폴더 선택 모드 활성화 (이게 없으면 파일 선택창이 됨)
                dialog.IsFolderPicker = true;
                
                dialog.Title = title;
                dialog.Multiselect = false;       // 다중 선택 방지
                dialog.EnsurePathExists = true;   // 존재하지 않는 경로 입력 방지
                dialog.AddToMostRecentlyUsedList = false; // MRU 목록 오염 방지
                dialog.AllowNonFileSystemItems = false;   // 가상 폴더 선택 방지

                // [핵심 2] 초기 경로 설정 (네트워크 경로 등)
                if (!string.IsNullOrEmpty(initialPath) && System.IO.Directory.Exists(initialPath))
                {
                    dialog.InitialDirectory = initialPath;
                }
                else
                {
                    // 기본값: 바탕화면
                    dialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 
                }

                // [핵심 3] 부모 핸들을 넘겨주어 완벽한 모달(Modal)로 동작하게 함
                if (dialog.ShowDialog(ownerHandle) == CommonFileDialogResult.Ok)
                {
                    return dialog.FileName; // 사용자가 선택한 폴더 경로
                }
            }

            return string.Empty; // 취소 버튼 누름
        }
    }
}

Step 2: 사용 방법 (Usage in Form)

메인 폼(FormMain)이나 설정 폼(FormConfig)에서 버튼을 눌렀을 때 사용하는 방법입니다.

파일명: FormConfig.cs

C#
 
using System;
using System.Windows.Forms;
using A2_SOP_Linescan.Utils; // 위에서 만든 Helper 네임스페이스

namespace A2_SOP_Linescan.UI
{
    public partial class FormConfig : Form
    {
        public FormConfig()
        {
            InitializeComponent();
        }

        private void btnSelectPath_Click(object sender, EventArgs e)
        {
            // 1. 현재 텍스트박스에 있는 경로를 초기값으로 줌
            string currentPath = txtSavePath.Text;

            // 2. 헬퍼 함수 호출 (this.Handle을 넘기는 것이 중요!)
            string selectedPath = DialogHelper.ShowFolderDialog(
                this.Handle, 
                currentPath, 
                "검사 이미지 저장 경로를 선택하세요"
            );

            // 3. 결과 처리 (빈 문자열이면 취소한 것임)
            if (!string.IsNullOrEmpty(selectedPath))
            {
                txtSavePath.Text = selectedPath;
                
                // (옵션) 로그 남기기
                // LogManager.Instance.Info($"저장 경로 변경됨: {selectedPath}");
            }
        }
    }
}

Step 3: 핵심 코드 분석

  1. dialog.IsFolderPicker = true;
    • 이 속성이 CommonOpenFileDialog의 정체성입니다.
    • true: 폴더 선택 창 (우리가 원하는 것)
    • false: 파일 열기 창 (일반적인 OpenFileDialog)
  2. dialog.ShowDialog(ownerHandle)
    • 인자 없이 ShowDialog()를 쓰면 다이얼로그가 폼 뒤로 숨거나, 사용자가 다이얼로그를 무시하고 폼을 조작할 수 있습니다.
    • this.Handle (IntPtr)을 넘겨주어야 윈도우 OS가 "이 다이얼로그는 저 폼의 자식이다"라고 인식하여, 부모 폼을 잠그고(Disable) 중앙에 띄워줍니다.
  3. CommonFileDialogResult.Ok
    • WinForms 기본 다이얼로그는 DialogResult.OK를 쓰지만, 이 라이브러리는 CommonFileDialogResult 열거형을 씁니다. 혼동하지 않도록 주의하십시오.

이 코드를 복사해서 Utils 폴더에 넣어두시면, 프로젝트 내 어디서든 한 줄로 멋진 탐색기 창을 띄울 수 있습니다.

반응형