성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] Roll A Lisp In C - Reading ; https...
[정성태] Java - How to use the Foreign Funct...
[정성태] 제가 큰 실수를 했군요. ^^; Delegate를 통한 Bein...
[정성태] Working with Rust Libraries from C#...
[정성태] Detecting blocking calls using asyn...
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>CommonOpenFileDialog 사용 시 사용자가 선택한 파일 목록을 구하는 방법</h1> <p> <a target='tab' href='http://www.sysnet.pe.kr/2/0/1516'>CommonOpenFileDialog</a>를 다음과 같이 사용하는 경우,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > var dialog = new CommonOpenFileDialog(); <span style='color: blue; font-weight: bold'>dialog.Multiselect = true;</span> if (dialog.ShowDialog() == CommonFileDialogResult.Ok) { // dialog.FileNames } </pre> <br /> 실제 사용하는 화면에서,<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='selected_files_in_opendlg_1.png' src='/SysWebRes/bbs/selected_files_in_opendlg_1.png' /><br /> <br /> 사용자가 "Program.cs", "App.config", "ConsoleApp1.csproj" 순으로 선택을 했음에도 불구하고 "File name: " 텍스트 상자에서 보이는 바와 같이 선택한 순서와 무관하게 배치되는 것을 볼 수 있습니다. 또한, "dialog.FileNames" 속성으로 반환받은 목록도 순서와 상관없이 "File name: " 텍스트 상자에 보이는 값이 그대로 반환됩니다.<br /> <br /> 그렇다면 선택된 순서를 반영한 목록을 가져오고 싶다면 어떻게 해야 할까요?<br /> <br /> 아쉽게도 이에 대해서는 공식적인 방법이 없습니다. 단지, 우회해서 구현해야 하는데요. 그나마 다행인 것은 CommonOpenFileDialog 타입이 SelectionChanged 이벤트를 제공한다는 점입니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > private void Form1_Load(object sender, EventArgs e) { var dialog = new CommonOpenFileDialog(); dialog.Multiselect = true; <span style='color: blue; font-weight: bold'>dialog.SelectionChanged += Dialog_SelectionChanged;</span> if (dialog.ShowDialog() == CommonFileDialogResult.Ok) { } } private void Dialog_SelectionChanged(object sender, EventArgs e) { } </pre> <br /> 그런데, 여기서 한 가지 더 문제가 있습니다. 아직 "OK" 버튼을 누르지 않은 대화창인 경우에는 SelectionChanged 이벤트 처리기 안에서 어떤 파일이 선택되었는지 알 수 없다는 것입니다. 즉 CommonOpenFileDialog.FileNames 속성의 값을 구할 수 없습니다.<br /> <br /> 그래서 처음에 생각했던 방법이 대화창 자체를 Window 자원으로 열람하면서 텍스트 윈도우를 찾아 파일 선택 목록을 가져오는 것이었습니다. 매번 선택할 때마다 가져오면 이전 선택된 항목의 목록과 비교해 순서를 지정해 보자는 의도였는데요. 그런데 조금 살펴보니 이보다 더 좋은 방법이 있습니다.<br /> <br /> CommonOpenFileDialog의 부모 클래스인 CommonFileDialog에는 private으로 nativeDialog 필드를 가지고 있는데 이것이 IFileOpenDlg를 구현하고 있기 때문에 이것으로부터 선택된 파일의 목록을 구할 수 있습니다. 물론, private이기 때문에 Reflection을 사용해야 하지만 어쨌든 다음과 같이 선택된 파일 목록을 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > private void Dialog_SelectionChanged(object sender, EventArgs e) { CommonOpenFileDialog dlg = sender as CommonOpenFileDialog; FieldInfo fi = dlg.GetType().BaseType.GetField("nativeDialog", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance); object nativeDialog = fi.GetValue(dlg); IFileOpenDlg odlg = nativeDialog as IFileOpenDlg; if (odlg == null) { return; } try { odlg.GetSelectedItems(out IShellItemArray ppsai); ppsai.GetCount(out uint itemCount); <span style='color: blue; font-weight: bold'>List<string> fileNames = new List<string>();</span> for (uint i = 0; i < itemCount; i++) { ppsai.GetItemAt(i, out IShellItem ppsi); ppsi.GetDisplayName(ShellItemDesignNameOptions.FileSystemPath, out IntPtr ppszName); string filePath = Marshal.PtrToStringUni(ppszName); <span style='color: blue; font-weight: bold'>fileNames.Add(filePath);</span> } } catch (Exception) { } } </pre> <br /> fileNames 목록을 구했으니, 이제 이전 선택된 내용과 비교해서 순서를 정해 주면 됩니다. <br /> <br /> (<a target='tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1184&boardid=331301885'>모든 기능을 구현한 코드는 첨부 파일에 넣어 두었으니 참고</a>하세요.)<br /> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
5788
(왼쪽의 숫자를 입력해야 합니다.)