폴더를 선택하도록 OpenFileDialog를 구성하려면 어떻게 해야 합니까?
VS .NET에서는 프로젝트의 폴더를 선택할 때 OpenFileDialog 또는 SaveFileDialog와 같은 대화상자가 표시되지만 폴더만 허용하도록 설정됩니다.이걸 본 이후로 어떻게 하는지 궁금했어요FolderBrowserDialog는 알고 있습니다만, 그 대화 상자가 마음에 들지 않습니다.너무 작게 시작해서 경로를 입력할 수 있는 이점을 얻을 수 없습니다.
이제 에서는 이 작업을 수행할 방법이 없을 것입니다.NET, 하지만 관리되지 않는 코드에서도 어떻게 하는지 궁금하네요.대화상자를 처음부터 완전히 재실장하는 것 외에 이 동작을 하도록 대화상자를 수정하려면 어떻게 해야 합니까?
또한 FolderBrowserDialog는 알고 있지만 이러한 방법으로 대화상자를 구성하는 방법이 궁금할 뿐만 아니라 사용하지 않을 수도 있습니다.FolderBrowserDialog를 사용하면 일관된 UI 환경을 유지할 수 있지만 궁금증이 충족되지 않아 답변으로 간주되지 않습니다.
Vista 고유의 것도 아니고, VS부터 이 다이얼로그를 표시하고 있습니다.NET 2003 이므로, Win2000 및 WinXP 로 실행할 수 있습니다.이 질문은 '적절한 방법을 알고 싶다'는 질문보다는 'VS 2003에서 처음 하고 싶었을 때부터 궁금했다'는 질문입니다.Vista의 파일 대화상자에는 이 작업을 수행할 수 있는 옵션이 있는 것은 알고 있습니다만, XP에서 동작하고 있기 때문에 동작시키기 위해 뭔가 조치를 취한 것으로 알고 있습니다.Vista 고유의 답변은 답변이 아닙니다.Vista는 질문 컨텍스트에 존재하지 않기 때문입니다.
업데이트: Scott Wisniewski의 답변은 작업용 샘플과 함께 제공되기 때문에 받아들이지만, 저는 Serge가 대화상자의 커스터마이즈를 지적한 것은 평가할 만하다고 생각합니다.NET 단, 동작합니다) 및 마크 랜섬을 통해 MS가 이 태스크에 대해 커스텀대화상자를 전개했을 가능성이 있음을 알 수 있습니다.
폴더 또는 파일을 열 수 있는 OpenFileOrFolder 대화 상자라는 대화 상자가 있습니다.
AcceptFiles 값을 false로 설정하면 폴더 수락 모드에서만 작동합니다.
Windows API windows windows windows windows 。껍데기와 관련된 것들이 많이 들어있어요CommonOpenFileDialog
)Microsoft.WindowsAPICodePack.Dialogs
★★★★★★★★★★★★★★★★」이치노폴더만 표시되는 일반적인 대화 상자입니다.
다음은 사용 방법의 예입니다.
CommonOpenFileDialog cofd = new CommonOpenFileDialog();
cofd.IsFolderPicker = true;
cofd.ShowDialog();
안타깝게도 Microsoft는 이 패키지를 더 이상 출하하지 않지만 몇몇 사용자가 비공식적으로 NuGet에 바이너리를 업로드했습니다.한 가지 예를 여기서 찾을 수 있습니다.이 패키지는 껍데기 전용입니다.필요한 경우 동일한 사용자가 원래 패키지에 더 많은 기능을 제공하는 다른 패키지를 여러 개 가지고 있습니다.
기본 제공 FolderBrowserDialog의 재사용 가능한 파생 모델인 FolderBrowserDialogEx를 사용할 수 있습니다.이 기능을 사용하면 경로를 입력할 수 있습니다. UNC 경로도 입력할 수 있습니다.또한 이를 사용하여 시스템 또는 프린터를 찾아볼 수도 있습니다.내장된 FBD처럼 작동하지만... 더 낫습니다.
(EDIT: 이 대화상자는 파일 또는 폴더를 선택하도록 설정할 수 있습니다.)
풀 소스 코드(1개의 짧은 C# 모듈).무료. MS-Public 라이센스.
사용할 코드:
var dlg1 = new Ionic.Utils.FolderBrowserDialogEx();
dlg1.Description = "Select a folder to extract to:";
dlg1.ShowNewFolderButton = true;
dlg1.ShowEditBox = true;
//dlg1.NewStyle = false;
dlg1.SelectedPath = txtExtractDirectory.Text;
dlg1.ShowFullPathInEditBox = true;
dlg1.RootFolder = System.Environment.SpecialFolder.MyComputer;
// Show the FolderBrowserDialog.
DialogResult result = dlg1.ShowDialog();
if (result == DialogResult.OK)
{
txtExtractDirectory.Text = dlg1.SelectedPath;
}
오오키이.대화 상자 패키지에는 새(Vista 스타일) 폴더 브라우저 대화 상자 주위에 관리되는 래퍼가 포함되어 있습니다.또, 낡은 operating system에서는, 대폭 저하합니다.
- WPF 타겟팅용 Ookii 대화상자.NET 4.5 및 NuGet에서 사용 가능
- Ookii Dialogs for Windows Forms 타겟팅.NET 4.5 및 NuGet에서 사용 가능
이 경우 FolderBrowserDialog를 사용하는 것이 좋습니다.
using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
dlg.Description = "Select a folder";
if (dlg.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("You selected: " + dlg.SelectedPath);
}
}
몇 시간 동안 검색한 결과, 유효한 솔루션에 대한 leet Night Shade의 답변을 찾았습니다.
이 솔루션이 다른 솔루션보다 훨씬 낫다고 생각하는 세 가지가 있습니다.
- 사용법은 간단합니다.프로젝트에 2개의 파일(어차피 1개로 결합 가능)만 포함하면 됩니다.
- XP 이전 시스템에서 사용할 경우 표준 FolderBrowserDialog로 돌아갑니다.
- 작성자는 사용자가 적합하다고 생각하는 모든 목적으로 코드를 사용할 수 있는 권한을 부여합니다.
자유롭게 코드를 사용할 수 있는 라이선스는 없습니다.
여기서 코드를 다운로드합니다.
네, 첫 번째 점을 연결해 보겠습니다.-) Spy+ 또는 Winspector를 사용하여 조금 재생하면 VS Project Location의 Folder 텍스트 상자가 표준 대화상자의 커스터마이즈임을 나타냅니다.이 필드는 메모장에 있는 것과 같은 표준 파일 대화상자의 파일 이름 텍스트 상자와 다릅니다.
여기서부터 VS는 파일 이름 및 파일 형식 텍스트 상자/콤보 상자를 숨기고 커스텀 대화 상자 템플릿을 사용하여 대화상자 하단에 자체 부분을 추가합니다.
편집: 이러한 커스터마이즈의 예와 그 방법을 다음에 나타냅니다(Win32에서는).네트워크):
m_ofn은 파일 대화상자의 기반이 되는 OPENFILNAME 구조체입니다.다음 두 줄을 추가합니다.
m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEDIALOG_IMPORTXLIFF);
m_ofn.Flags |= OFN_ENABLETEMPLATE;
여기서 IDD_FILEDIALOG_IPORTXLIFF는 대화상자 하단에 추가하는 커스텀대화 템플릿입니다.아래의 빨간색 부분을 참조하십시오.
(출처 : apptranslator.com )
이 경우 커스터마이즈된 부품은 레이블 + 하이퍼링크일 뿐이지만 모든 대화 상자가 될 수 있습니다.폴더만 선택할 수 있는 확인 버튼을 포함할 수 있습니다.
하지만 대화 상자의 표준 부분에 있는 일부 컨트롤을 어떻게 제거할지는 모르겠습니다.
Windows XP 에서는, 정확한 오디오 카피가 이 방법으로 동작합니다.표준 파일 열기 대화상자가 표시되지만 파일 이름 필드에는 "Filename will be ignored"라는 텍스트가 포함되어 있습니다.
추측입니다만, 대화 상자가 크게 변경될 때마다 콤보 상자 편집 컨트롤에 문자열이 삽입되는 것 같습니다.필드가 비어 있지 않고 파일의 존재를 확인하지 않도록 대화 상자 플래그가 설정되어 있으면 대화 상자를 정상적으로 닫을 수 있습니다.
편집: 생각했던 것보다 훨씬 쉬워요.이것은 C++/MFC의 코드입니다.선택한환경으로변환할수있습니다.
CFileDialog dlg(true, NULL, "Filename will be ignored", OFN_HIDEREADONLY | OFN_NOVALIDATE | OFN_PATHMUSTEXIST | OFN_READONLY, NULL, this);
dlg.DoModal();
편집 2: 이것은 C#으로 번역해야 하는데, 저는 C#에 능통하지 못하니까 안 되면 쏘지 마세요.
OpenFileDialog openFileDialog1 = new OpenFileDialog();
openFileDialog1.FileName = "Filename will be ignored";
openFileDialog1.CheckPathExists = true;
openFileDialog1.ShowReadOnly = false;
openFileDialog1.ReadOnlyChecked = true;
openFileDialog1.CheckFileExists = false;
openFileDialog1.ValidateNames = false;
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
// openFileDialog1.FileName should contain the folder and a dummy filename
}
편집 3: Visual Studio 2005에서 문제의 실제 대화 상자를 확인했습니다(이전에는 액세스할 수 없었습니다).표준 파일 열기 대화 상자가 아닙니다!Spy++에서 창을 검사하고 열려 있는 표준 파일과 비교하면 구조와 클래스 이름이 일치하지 않습니다.자세히 살펴보면 대화상자의 내용 간에 몇 가지 차이점도 발견할 수 있습니다.결론적으로 Microsoft는 이 기능을 제공하기 위해 Visual Studio의 표준 대화상자를 완전히 대체했습니다.내 솔루션이나 비슷한 것이 가능한 한 가까이 있을 것이다. 만약 당신이 처음부터 스스로 코드를 만들 의사가 없다면 말이다.
파일 대화 상자를 하위 분류하고 모든 컨트롤에 액세스할 수 있습니다.각각 창 핸들을 얻기 위해 사용할 수 있는 식별자가 있습니다.그런 다음 표시 및 숨기기, 선택 변경에 대한 메시지를 얻을 수 있습니다.모든 것은 당신이 얼마나 노력하고 싶은지에 달려있다.
WTL 클래스 지원을 사용하여 파일 대화상자를 커스텀 플레이스바 및 플러그인 COM 뷰를 포함하도록 커스터마이즈했습니다.
MSDN 에서는 Win32 를 사용한 방법에 대해 설명하고 있습니다.이 CodeProject 문서에는 예가 기재되어 있습니다.이 CodeProject 문서에는 을 기재하고 있습니다.NET의 예
할 수 .
- 는 파일 입니다.
- first 입니다.
파일 이름의 텍스트 상자를 숨기려면 OpenFileDialogEx를 확인해야 합니다.
★★★★
{
openFileDialog2.FileName = "\r";
openFileDialog1.Filter = "folders|*.neverseenthisfile";
openFileDialog1.CheckFileExists = false;
openFileDialog1.CheckPathExists = false;
}
Vista에서 VS2008을 사용하고 계십니까?이 경우 Vista 파일대화상자 IFileDialog를 호출할 때 FOS_PICKFOLDERS 옵션이 사용되고 있다고 생각합니다.에 있는 것 같습니다.NET 코드에는, 작업을 실시하기 위해서 많은 gnarly P/Invoke interop 코드가 필요합니다.
첫 번째 솔루션
저는 이것을 의 정리 버전으로 개발했습니다.lyquidity.com의 Bill Seddon이 작성한 NET Win 7 스타일의 폴더 선택 대화상자(저는 제휴 관계가 없습니다).(이 페이지의 다른 답변에서 코드를 알게 되었습니다).그의 솔루션에는 이러한 집중적인 목적에 필요하지 않고 예외 기반 흐름 제어를 사용하며 반사 호출 결과를 캐시하지 않는 추가 Reflection 클래스가 필요하기 때문에 제가 직접 작성했습니다.네스트된 스태틱은VistaDialog
는 class가 static 변수를 하지 않도록 Show
이치노윈도 비스타Windows 7, 8, 9, 10 이 windows ( windows적에 ) 。
using System;
using System.Reflection;
using System.Windows.Forms;
namespace ErikE.Shuriken {
/// <summary>
/// Present the Windows Vista-style open file dialog to select a folder. Fall back for older Windows Versions
/// </summary>
public class FolderSelectDialog {
private string _initialDirectory;
private string _title;
private string _fileName = "";
public string InitialDirectory {
get { return string.IsNullOrEmpty(_initialDirectory) ? Environment.CurrentDirectory : _initialDirectory; }
set { _initialDirectory = value; }
}
public string Title {
get { return _title ?? "Select a folder"; }
set { _title = value; }
}
public string FileName { get { return _fileName; } }
public bool Show() { return Show(IntPtr.Zero); }
/// <param name="hWndOwner">Handle of the control or window to be the parent of the file dialog</param>
/// <returns>true if the user clicks OK</returns>
public bool Show(IntPtr hWndOwner) {
var result = Environment.OSVersion.Version.Major >= 6
? VistaDialog.Show(hWndOwner, InitialDirectory, Title)
: ShowXpDialog(hWndOwner, InitialDirectory, Title);
_fileName = result.FileName;
return result.Result;
}
private struct ShowDialogResult {
public bool Result { get; set; }
public string FileName { get; set; }
}
private static ShowDialogResult ShowXpDialog(IntPtr ownerHandle, string initialDirectory, string title) {
var folderBrowserDialog = new FolderBrowserDialog {
Description = title,
SelectedPath = initialDirectory,
ShowNewFolderButton = false
};
var dialogResult = new ShowDialogResult();
if (folderBrowserDialog.ShowDialog(new WindowWrapper(ownerHandle)) == DialogResult.OK) {
dialogResult.Result = true;
dialogResult.FileName = folderBrowserDialog.SelectedPath;
}
return dialogResult;
}
private static class VistaDialog {
private const string c_foldersFilter = "Folders|\n";
private const BindingFlags c_flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
private readonly static Assembly s_windowsFormsAssembly = typeof(FileDialog).Assembly;
private readonly static Type s_iFileDialogType = s_windowsFormsAssembly.GetType("System.Windows.Forms.FileDialogNative+IFileDialog");
private readonly static MethodInfo s_createVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("CreateVistaDialog", c_flags);
private readonly static MethodInfo s_onBeforeVistaDialogMethodInfo = typeof(OpenFileDialog).GetMethod("OnBeforeVistaDialog", c_flags);
private readonly static MethodInfo s_getOptionsMethodInfo = typeof(FileDialog).GetMethod("GetOptions", c_flags);
private readonly static MethodInfo s_setOptionsMethodInfo = s_iFileDialogType.GetMethod("SetOptions", c_flags);
private readonly static uint s_fosPickFoldersBitFlag = (uint) s_windowsFormsAssembly
.GetType("System.Windows.Forms.FileDialogNative+FOS")
.GetField("FOS_PICKFOLDERS")
.GetValue(null);
private readonly static ConstructorInfo s_vistaDialogEventsConstructorInfo = s_windowsFormsAssembly
.GetType("System.Windows.Forms.FileDialog+VistaDialogEvents")
.GetConstructor(c_flags, null, new[] { typeof(FileDialog) }, null);
private readonly static MethodInfo s_adviseMethodInfo = s_iFileDialogType.GetMethod("Advise");
private readonly static MethodInfo s_unAdviseMethodInfo = s_iFileDialogType.GetMethod("Unadvise");
private readonly static MethodInfo s_showMethodInfo = s_iFileDialogType.GetMethod("Show");
public static ShowDialogResult Show(IntPtr ownerHandle, string initialDirectory, string title) {
var openFileDialog = new OpenFileDialog {
AddExtension = false,
CheckFileExists = false,
DereferenceLinks = true,
Filter = c_foldersFilter,
InitialDirectory = initialDirectory,
Multiselect = false,
Title = title
};
var iFileDialog = s_createVistaDialogMethodInfo.Invoke(openFileDialog, new object[] { });
s_onBeforeVistaDialogMethodInfo.Invoke(openFileDialog, new[] { iFileDialog });
s_setOptionsMethodInfo.Invoke(iFileDialog, new object[] { (uint) s_getOptionsMethodInfo.Invoke(openFileDialog, new object[] { }) | s_fosPickFoldersBitFlag });
var adviseParametersWithOutputConnectionToken = new[] { s_vistaDialogEventsConstructorInfo.Invoke(new object[] { openFileDialog }), 0U };
s_adviseMethodInfo.Invoke(iFileDialog, adviseParametersWithOutputConnectionToken);
try {
int retVal = (int) s_showMethodInfo.Invoke(iFileDialog, new object[] { ownerHandle });
return new ShowDialogResult {
Result = retVal == 0,
FileName = openFileDialog.FileName
};
}
finally {
s_unAdviseMethodInfo.Invoke(iFileDialog, new[] { adviseParametersWithOutputConnectionToken[1] });
}
}
}
// Wrap an IWin32Window around an IntPtr
private class WindowWrapper : IWin32Window {
private readonly IntPtr _handle;
public WindowWrapper(IntPtr handle) { _handle = handle; }
public IntPtr Handle { get { return _handle; } }
}
}
}
Windows 폼에서는 다음과 같이 사용됩니다.
var dialog = new FolderSelectDialog {
InitialDirectory = musicFolderTextBox.Text,
Title = "Select a folder to import music from"
};
if (dialog.Show(Handle)) {
musicFolderTextBox.Text = dialog.FileName;
}
물론 옵션과 어떤 속성을 가지고 놀 수 있습니다.예를 들어 Vista 스타일 대화상자에서 여러 항목을 선택할 수 있습니다.
두 번째 솔루션
Simon Mourier는 Windows API에 대해 직접 interop을 사용하여 동일한 작업을 수행하는 방법을 보여주는 답변을 제공했지만, 이전 버전의 Windows에서 이전 스타일의 대화상자를 사용하려면 그의 버전을 보완해야 합니다.안타깝게도, 저는 해결책을 마련했을 때 아직 그의 자리를 찾지 못했습니다.독약 말해!
Codeproject(Nitron에 크레디트)에서 다음을 시험해 보십시오.
말씀하신 것과 같은 대화상자인 것 같습니다.스크린샷을 추가하면 도움이 될까요?
bool GetFolder(std::string& folderpath, const char* szCaption=NULL, HWND hOwner=NULL)
{
bool retVal = false;
// The BROWSEINFO struct tells the shell how it should display the dialog.
BROWSEINFO bi;
memset(&bi, 0, sizeof(bi));
bi.ulFlags = BIF_USENEWUI;
bi.hwndOwner = hOwner;
bi.lpszTitle = szCaption;
// must call this if using BIF_USENEWUI
::OleInitialize(NULL);
// Show the dialog and get the itemIDList for the selected folder.
LPITEMIDLIST pIDL = ::SHBrowseForFolder(&bi);
if(pIDL != NULL)
{
// Create a buffer to store the path, then get the path.
char buffer[_MAX_PATH] = {'\0'};
if(::SHGetPathFromIDList(pIDL, buffer) != 0)
{
// Set the string value.
folderpath = buffer;
retVal = true;
}
// free the item id list
CoTaskMemFree(pIDL);
}
::OleUninitialize();
return retVal;
}
Vista 에서는, IFileDialog 와 FOS_PICKFOLDERS 옵션 세트를 사용할 수 있습니다.폴더를 선택할 수 있는 OpenFileDialog와 같은 창이 나타납니다.
var frm = (IFileDialog)(new FileOpenDialogRCW());
uint options;
frm.GetOptions(out options);
options |= FOS_PICKFOLDERS;
frm.SetOptions(options);
if (frm.Show(owner.Handle) == S_OK) {
IShellItem shellItem;
frm.GetResult(out shellItem);
IntPtr pszString;
shellItem.GetDisplayName(SIGDN_FILESYSPATH, out pszString);
this.Folder = Marshal.PtrToStringAuto(pszString);
}
이전 Windows의 경우 폴더의 파일을 선택하여 언제든지 트릭을 사용할 수 있습니다.
에서 동작하는 작업 예.NET Framework 2.0 이후는, 여기를 참조해 주세요.
이렇게 코드를 사용할 수 있습니다.
필터가 빈 문자열입니다.파일명은 AnyName이지만 공백은 아닙니다.
openFileDialog.FileName = "AnyFile";
openFileDialog.Filter = string.Empty;
openFileDialog.CheckFileExists = false;
openFileDialog.CheckPathExists = false;
Ookii Dialogs for WPF 라이브러리에는 WPF용 폴더 브라우저 대화상자를 구현하는 클래스가 있습니다.
Windows Forms에서 사용할 수 있는 버전도 있습니다.
질문의 내용은 다음 구성인 것을 알고 있습니다.OpenFileDialog
그러나 구글이 나를 여기로 데려온 것을 보면, 만약 당신이 폴더만을 찾고 있다면, 당신은 그것을 사용해야 한다고 지적하는 것이 좋을 것이다.FolderBrowserDialog
대신 아래의 다른 SO 질문에 대한 답변이 있습니다.
vb.net에서 열린 파일 대화 상자를 사용하여 경로를 지정하려면 어떻게 해야 합니까?
언급URL : https://stackoverflow.com/questions/31059/how-do-you-configure-an-openfiledialog-to-select-folders
'programing' 카테고리의 다른 글
공유 호스트의 "LOG_BACKUP" 때문에 데이터베이스의 트랜잭션 로그가 가득 찼습니다." (0) | 2023.04.19 |
---|---|
python 목록의 n번째 요소 또는 기본값을 가져오는 방법(사용할 수 없는 경우) (0) | 2023.04.19 |
SQL에서 EXISTS와 IN의 차이점은 무엇입니까? (0) | 2023.04.19 |
Swift에서 어레이에 요소 추가 (0) | 2023.04.19 |
Python에서 파일을 이동하려면 어떻게 해야 하나요? (0) | 2023.04.19 |