OpenFileDialog를 사용하여 폴더를 선택하는 방법은 무엇입니까?
저는 다음 프로젝트를 사용하려고 했습니다: https://github.com/scottwis/OpenFileOrFolderDialog
하지만, 문제가 있습니다: 그것은 그것을 사용합니다.GetOpenFileName
기능 및OPENFILENAME
구조. OPENFILENAME
멤버 이름이 지정되어 있습니다.templateID
대화 상자 템플릿의 식별자입니다.그리고 프로젝트는 다음을 포함합니다.res1.rc
파일 및 템플릿 대화 상자도 포함됩니다.하지만 저는 이 파일을 제 C# 프로젝트에 어떻게 첨부해야 하는지 알 수 없었습니다.
더 나은 사용 방법이 있습니까?OpenFileDialog
폴더를 선택하시겠습니까?
기본적으로 클래스가 필요합니다.
사용자에게 폴더를 선택하라는 메시지를 표시합니다.이 클래스는 상속할 수 없습니다.
예:
using(var fbd = new FolderBrowserDialog())
{
DialogResult result = fbd.ShowDialog();
if (result == DialogResult.OK && !string.IsNullOrWhiteSpace(fbd.SelectedPath))
{
string[] files = Directory.GetFiles(fbd.SelectedPath);
System.Windows.Forms.MessageBox.Show("Files found: " + files.Length.ToString(), "Message");
}
}
WPF에서 작업하는 경우 다음에 참조를 추가해야 합니다.System.Windows.Forms
.
또한 추가해야 합니다.using System.IO
위해서Directory
학급
사용을 피하고 싶은 미래의 사용자를 위한 참고 사항FolderBrowserDialog
마이크로소프트는 윈도우라고 불리는 API를 출시한 적이 있습니다.다음과 같은 유용한 대화상자가 있는 API CodePackCommonOpenFileDialog
그것은 다음과 같이 설정될 수 있습니다.IsFolderPicker
이 API는 Microsoft에서 NuGet 패키지로 제공됩니다.
설치 및 사용에 필요한 것은 이것뿐입니다.CommonOpenFileDialog
(NuGet이 종속성을 처리함
Install-Package Microsoft.WindowsAPICodePack-Shell
포함 줄의 경우:
using Microsoft.WindowsAPICodePack.Dialogs;
용도:
CommonOpenFileDialog dialog = new CommonOpenFileDialog();
dialog.InitialDirectory = "C:\\Users";
dialog.IsFolderPicker = true;
if (dialog.ShowDialog() == CommonFileDialogResult.Ok)
{
MessageBox.Show("You selected: " + dialog.FileName);
}
다음을 사용하는 해킹 솔루션이 있습니다.OpenFileDialog
어디에ValidateNames
그리고.CheckFileExists
둘 다 false로 설정됩니다.FileName
디렉토리가 선택되었음을 나타내는 모의 값이 제공됩니다.
나는 폴더를 선택하는 방법에 대해 사용자들에게 혼란을 주기 때문에 해킹이라고 말합니다.파일 이름이 "폴더 선택"으로 표시된 상태에서 원하는 폴더에 있어야 합니다.
이것은 Denis Stankovski의 동일한 대화상자에서 파일 또는 폴더 선택에 기초합니다.
OpenFileDialog folderBrowser = new OpenFileDialog();
// Set validate names and check file exists to false otherwise windows will
// not let you select "Folder Selection."
folderBrowser.ValidateNames = false;
folderBrowser.CheckFileExists = false;
folderBrowser.CheckPathExists = true;
// Always default to Folder Selection.
folderBrowser.FileName = "Folder Selection.";
if (folderBrowser.ShowDialog() == DialogResult.OK)
{
string folderPath = Path.GetDirectoryName(folderBrowser.FileName);
// ...
}
모든 버전에서 사용할 수 있는 순수한 C# 버전이 있습니다.NET(포함).NET Core, .NET 5, WPF, Winforms 등) 및 FOS_PICK FOLDES 옵션이 있는 Windows Vista 이상의 IFileDialog 인터페이스를 사용하여 멋진 폴더 선택기 Windows 표준 UI를 제공합니다.
2023/3/17 업데이트: 이제 클래스가 다중 선택을 지원합니다.
WPF도 추가했습니다.Window
WPF로 표시된 줄은 제거할 수 있습니다.
용도:
var dlg = new FolderPicker();
dlg.InputPath = @"c:\windows\system32";
if (dlg.ShowDialog() == true)
{
MessageBox.Show(dlg.ResultPath);
}
코드:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Windows;
using System.Windows.Interop;
public class FolderPicker
{
private readonly List<string> _resultPaths = new List<string>();
private readonly List<string> _resultNames = new List<string>();
public IReadOnlyList<string> ResultPaths => _resultPaths;
public IReadOnlyList<string> ResultNames => _resultNames;
public string ResultPath => ResultPaths.FirstOrDefault();
public string ResultName => ResultNames.FirstOrDefault();
public virtual string InputPath { get; set; }
public virtual bool ForceFileSystem { get; set; }
public virtual bool Multiselect { get; set; }
public virtual string Title { get; set; }
public virtual string OkButtonLabel { get; set; }
public virtual string FileNameLabel { get; set; }
protected virtual int SetOptions(int options)
{
if (ForceFileSystem)
{
options |= (int)FOS.FOS_FORCEFILESYSTEM;
}
if (Multiselect)
{
options |= (int)FOS.FOS_ALLOWMULTISELECT;
}
return options;
}
// for WPF support
public bool? ShowDialog(Window owner = null, bool throwOnError = false)
{
owner = owner ?? Application.Current?.MainWindow;
return ShowDialog(owner != null ? new WindowInteropHelper(owner).Handle : IntPtr.Zero, throwOnError);
}
// for all .NET
public virtual bool? ShowDialog(IntPtr owner, bool throwOnError = false)
{
var dialog = (IFileOpenDialog)new FileOpenDialog();
if (!string.IsNullOrEmpty(InputPath))
{
if (CheckHr(SHCreateItemFromParsingName(InputPath, null, typeof(IShellItem).GUID, out var item), throwOnError) != 0)
return null;
dialog.SetFolder(item);
}
var options = FOS.FOS_PICKFOLDERS;
options = (FOS)SetOptions((int)options);
dialog.SetOptions(options);
if (Title != null)
{
dialog.SetTitle(Title);
}
if (OkButtonLabel != null)
{
dialog.SetOkButtonLabel(OkButtonLabel);
}
if (FileNameLabel != null)
{
dialog.SetFileName(FileNameLabel);
}
if (owner == IntPtr.Zero)
{
owner = Process.GetCurrentProcess().MainWindowHandle;
if (owner == IntPtr.Zero)
{
owner = GetDesktopWindow();
}
}
var hr = dialog.Show(owner);
if (hr == ERROR_CANCELLED)
return null;
if (CheckHr(hr, throwOnError) != 0)
return null;
if (CheckHr(dialog.GetResults(out var items), throwOnError) != 0)
return null;
items.GetCount(out var count);
for (var i = 0; i < count; i++)
{
items.GetItemAt(i, out var item);
CheckHr(item.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEPARSING, out var path), throwOnError);
CheckHr(item.GetDisplayName(SIGDN.SIGDN_DESKTOPABSOLUTEEDITING, out var name), throwOnError);
if (path != null || name != null)
{
_resultPaths.Add(path);
_resultNames.Add(name);
}
}
return true;
}
private static int CheckHr(int hr, bool throwOnError)
{
if (hr != 0 && throwOnError) Marshal.ThrowExceptionForHR(hr);
return hr;
}
[DllImport("shell32")]
private static extern int SHCreateItemFromParsingName([MarshalAs(UnmanagedType.LPWStr)] string pszPath, IBindCtx pbc, [MarshalAs(UnmanagedType.LPStruct)] Guid riid, out IShellItem ppv);
[DllImport("user32")]
private static extern IntPtr GetDesktopWindow();
#pragma warning disable IDE1006 // Naming Styles
private const int ERROR_CANCELLED = unchecked((int)0x800704C7);
#pragma warning restore IDE1006 // Naming Styles
[ComImport, Guid("DC1C5A9C-E88A-4dde-A5A1-60F82A20AEF7")] // CLSID_FileOpenDialog
private class FileOpenDialog { }
[ComImport, Guid("d57c7288-d4ad-4768-be02-9d969532d960"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IFileOpenDialog
{
[PreserveSig] int Show(IntPtr parent); // IModalWindow
[PreserveSig] int SetFileTypes(); // not fully defined
[PreserveSig] int SetFileTypeIndex(int iFileType);
[PreserveSig] int GetFileTypeIndex(out int piFileType);
[PreserveSig] int Advise(); // not fully defined
[PreserveSig] int Unadvise();
[PreserveSig] int SetOptions(FOS fos);
[PreserveSig] int GetOptions(out FOS pfos);
[PreserveSig] int SetDefaultFolder(IShellItem psi);
[PreserveSig] int SetFolder(IShellItem psi);
[PreserveSig] int GetFolder(out IShellItem ppsi);
[PreserveSig] int GetCurrentSelection(out IShellItem ppsi);
[PreserveSig] int SetFileName([MarshalAs(UnmanagedType.LPWStr)] string pszName);
[PreserveSig] int GetFileName([MarshalAs(UnmanagedType.LPWStr)] out string pszName);
[PreserveSig] int SetTitle([MarshalAs(UnmanagedType.LPWStr)] string pszTitle);
[PreserveSig] int SetOkButtonLabel([MarshalAs(UnmanagedType.LPWStr)] string pszText);
[PreserveSig] int SetFileNameLabel([MarshalAs(UnmanagedType.LPWStr)] string pszLabel);
[PreserveSig] int GetResult(out IShellItem ppsi);
[PreserveSig] int AddPlace(IShellItem psi, int alignment);
[PreserveSig] int SetDefaultExtension([MarshalAs(UnmanagedType.LPWStr)] string pszDefaultExtension);
[PreserveSig] int Close(int hr);
[PreserveSig] int SetClientGuid(); // not fully defined
[PreserveSig] int ClearClientData();
[PreserveSig] int SetFilter([MarshalAs(UnmanagedType.IUnknown)] object pFilter);
[PreserveSig] int GetResults(out IShellItemArray ppenum);
[PreserveSig] int GetSelectedItems([MarshalAs(UnmanagedType.IUnknown)] out object ppsai);
}
[ComImport, Guid("43826D1E-E718-42EE-BC55-A1E261C37BFE"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellItem
{
[PreserveSig] int BindToHandler(); // not fully defined
[PreserveSig] int GetParent(); // not fully defined
[PreserveSig] int GetDisplayName(SIGDN sigdnName, [MarshalAs(UnmanagedType.LPWStr)] out string ppszName);
[PreserveSig] int GetAttributes(); // not fully defined
[PreserveSig] int Compare(); // not fully defined
}
[ComImport, Guid("b63ea76d-1f85-456f-a19c-48159efa858b"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
private interface IShellItemArray
{
[PreserveSig] int BindToHandler(); // not fully defined
[PreserveSig] int GetPropertyStore(); // not fully defined
[PreserveSig] int GetPropertyDescriptionList(); // not fully defined
[PreserveSig] int GetAttributes(); // not fully defined
[PreserveSig] int GetCount(out int pdwNumItems);
[PreserveSig] int GetItemAt(int dwIndex, out IShellItem ppsi);
[PreserveSig] int EnumItems(); // not fully defined
}
#pragma warning disable CA1712 // Do not prefix enum values with type name
private enum SIGDN : uint
{
SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000,
SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,
SIGDN_FILESYSPATH = 0x80058000,
SIGDN_NORMALDISPLAY = 0,
SIGDN_PARENTRELATIVE = 0x80080001,
SIGDN_PARENTRELATIVEEDITING = 0x80031001,
SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8007c001,
SIGDN_PARENTRELATIVEPARSING = 0x80018001,
SIGDN_URL = 0x80068000
}
[Flags]
private enum FOS
{
FOS_OVERWRITEPROMPT = 0x2,
FOS_STRICTFILETYPES = 0x4,
FOS_NOCHANGEDIR = 0x8,
FOS_PICKFOLDERS = 0x20,
FOS_FORCEFILESYSTEM = 0x40,
FOS_ALLNONSTORAGEITEMS = 0x80,
FOS_NOVALIDATE = 0x100,
FOS_ALLOWMULTISELECT = 0x200,
FOS_PATHMUSTEXIST = 0x800,
FOS_FILEMUSTEXIST = 0x1000,
FOS_CREATEPROMPT = 0x2000,
FOS_SHAREAWARE = 0x4000,
FOS_NOREADONLYRETURN = 0x8000,
FOS_NOTESTFILECREATE = 0x10000,
FOS_HIDEMRUPLACES = 0x20000,
FOS_HIDEPINNEDPLACES = 0x40000,
FOS_NODEREFERENCELINKS = 0x100000,
FOS_OKBUTTONNEEDSINTERACTION = 0x200000,
FOS_DONTADDTORECENT = 0x2000000,
FOS_FORCESHOWHIDDEN = 0x10000000,
FOS_DEFAULTNOMINIMODE = 0x20000000,
FOS_FORCEPREVIEWPANEON = 0x40000000,
FOS_SUPPORTSTREAMABLEITEMS = unchecked((int)0x80000000)
}
#pragma warning restore CA1712 // Do not prefix enum values with type name
}
결과:
이상하게도 많은 답변/투표가 있지만 아무도 다음 코드를 답변으로 추가하지 않습니다.
using (var opnDlg = new OpenFileDialog()) //ANY dialog
{
//opnDlg.Filter = "Png Files (*.png)|*.png";
//opnDlg.Filter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx|CSV Files (*.csv)|*.csv"
if (opnDlg.ShowDialog() == DialogResult.OK)
{
//opnDlg.SelectedPath -- your result
}
}
FolderBrowserDialog(폴더 브라우저 대화 상자)를 찾는 것처럼 들립니다.
여기 간단한 ZIP 파일 하나로 모든 소스를 사용할 수 있는 또 다른 솔루션이 있습니다.
OpenFileDialog에는 Windows 7+ 폴더 선택 대화 상자처럼 작동하는 추가 창 플래그가 표시됩니다.
웹사이트에 따르면, 그것은 퍼블릭 도메인입니다: "당신이 원하는 것을 자유롭게 가져가고 코드로 할 수 있는 것과 같은 라이선스는 없습니다."
- 기사: .NET Win 7-style 폴더 선택 대화상자(http://www.lyquidity.com/devblog/ ?p=http)
- 소스 코드: http://s3downloads.lyquidity.com/FolderSelectDialog/FolderSelectDialog.zip
Archive.org 링크:
- 기사: https://web.archive.org/web/20180823181552/http ://www.lyquidity.com/devblog/ ?p=http://www.lyquidity.com/devblog/
- 소스 코드: https://web.archive.org/web/20180823181632/http ://s3downloads.lyquidity.com/FolderSelectDialog/FolderSelectDialog.zip
Windows Forms 및 WPF용 폴더 브라우저 대화 상자가 각각 구현된 Ookii Dialogs 라이브러리를 살펴봅니다.
좋아요, 대화.WinForms
좋아요, 대화.Wpf
저는 C#을 처음 접하게 되었는데, 방금 이 스레드를 발견했습니다.
이것은 언어에 익숙하지 않은 사람들에게도 흥미로울 수 있습니다.
OP 질문을 고려할 때 사이먼 모리어가 제시한 답변이 가장 좋을 것입니다.이것은 NuGET 패키지를 포함하지 않기 때문에 향후 폴더 방법 선택에 대한 의존성 문제는 없을 것입니다.
"...를 C# 7.3에서 사용할 수 없음"과 관련된 오류가 발생한 경우 다음을 추가합니다.<LangVersion>8.0</LangVersion>
.csproj로 (Visual Studio를 사용하여 테스트하면 빌드 및 실행 시 오류가 발생하지 않음)
프로젝트 언어를 변경할 수 없는 경우 소유자를 교체하십시오.??= Application.Current.MainWindow
와 함께
소유자 = 소유자 ?어플.현재의.주 창
Small Visual Basic에서 폴더 브라우저 대화 상자를 사용하는 방법입니다.이 코드는 선택되지 않은 초기 폴더 문제를 해결하고 클립보드 또는 레지스트리(있는 경우)에서 폴더를 선택합니다. 폴더가 삭제되면 기존 폴더를 선택할 때까지 상위 항목으로 이동합니다.이렇게 하면 대화 상자를 매우 편리하게 사용할 수 있습니다.새 폴더 만들기 단추를 표시하기 때문에 4개의 탭을 보내지만, 숨길 경우 두 개의 탭만 사용합니다.
Public Shared Function OpenFolderDialog(initialFolder As String) As String
Dim folder = GeIinitialFolder(initialFolder)
If folder = "" Then folder = GeIinitialFolder(System.Windows.Clipboard.GetText())
If folder = "" Then folder = GeIinitialFolder(GetSetting("sVB", "OpenFolder", "LastFolder", ""))
Dim th As New Threading.Thread(
Sub()
Threading.Thread.Sleep(300)
System.Windows.Forms.SendKeys.SendWait("{TAB}{TAB}{TAB}{TAB}{RIGHT}")
End Sub)
th.Start()
Try
Dim dlg As New System.Windows.Forms.FolderBrowserDialog With {
.Description = "Select a folder:",
.SelectedPath = folder
}
If dlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
SaveSetting("sVB", "OpenFolder", "LastFolder", dlg.SelectedPath)
OpenFolderDialog = dlg.SelectedPath
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Function
Private Shared Function GeIinitialFolder(folder As String) As String
Try
If folder <> "" Then
If IO.File.Exists(folder) Then
folder = Path.GetDirectoryName(folder)
Else
Do
If Directory.GetDirectoryRoot(folder) = folder OrElse Directory.Exists(folder) Then
Exit Do
End If
folder = Path.GetDirectoryName(folder)
Loop
End If
End If
Catch
folder = ""
End Try
Return folder
End Function
이것이 가장 분명하고 직선적인 방법이어야 합니다.
using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
if(result == System.Windows.Forms.DialogResult.OK)
{
selectedFolder = dialog.SelectedPath;
}
}
언급URL : https://stackoverflow.com/questions/11624298/how-do-i-use-openfiledialog-to-select-a-folder
'programing' 카테고리의 다른 글
MongoDB, 인덱스된 필드에 대한 정규식에 의한 쿼리 성능 (0) | 2023.05.03 |
---|---|
MSBuild TypeScript 컴파일 사용 안 함 (0) | 2023.05.03 |
현재 클래스를 반환 유형 주석으로 배치 (0) | 2023.05.03 |
현재 분기에 대한 추적 정보가 없습니다. (0) | 2023.05.03 |
배치 스크립트를 사용하여 디렉토리의 각 파일에 작업을 수행하는 방법 (0) | 2023.05.03 |