사용자가 생성 할 파일이 저장 될 디렉토리를 선택하기를 원합니다. WPF OpenFileDialog
에서 from Win32를 사용해야한다는 것을 알고 있지만 불행히도 대화 상자에는 파일을 선택해야합니다. 하나를 선택하지 않고 확인을 클릭하면 열린 상태로 유지됩니다. 사용자가 파일을 선택한 다음 경로를 제거하여 파일이 속한 디렉토리를 알아낼 수는 있지만 직관적이지 않습니다. 이 일을 전에 본 사람이 있습니까?
사용자가 생성 할 파일이 저장 될 디렉토리를 선택하기를 원합니다. WPF OpenFileDialog
에서 from Win32를 사용해야한다는 것을 알고 있지만 불행히도 대화 상자에는 파일을 선택해야합니다. 하나를 선택하지 않고 확인을 클릭하면 열린 상태로 유지됩니다. 사용자가 파일을 선택한 다음 경로를 제거하여 파일이 속한 디렉토리를 알아낼 수는 있지만 직관적이지 않습니다. 이 일을 전에 본 사람이 있습니까?
답변:
이를 위해 내장 FolderBrowserDialog 클래스를 사용할 수 있습니다 . System.Windows.Forms
네임 스페이스 에 있다는 것을 신경 쓰지 마십시오 .
using (var dialog = new System.Windows.Forms.FolderBrowserDialog())
{
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
}
창을 일부 WPF 창에서 모달로 표시하려면 WPF 응용 프로그램에서 FolderBrowserDialog를 사용하는 방법 질문을 참조하십시오 .
편집 : 일반, 추악한 Windows Forms FolderBrowserDialog보다 조금 더 멋진 것을 원한다면 대신 Vista 대화 상자를 사용할 수있는 몇 가지 대안이 있습니다.
using Microsoft.WindowsAPICodePack.Dialogs;
...
var dialog = new CommonOpenFileDialog();
dialog.IsFolderPicker = true;
CommonFileDialogResult result = dialog.ShowDialog();
이 대화 상자는 Windows Vista 이전의 운영 체제에서는 사용할 수 없으므로 CommonFileDialog.IsPlatformSupported
먼저 확인하십시오 .
CommonOpenFileDialog
에서 WindowsAPICodePack
당신이 필요합니다 Install-Package WindowsAPICodePack-Shell
. 답변에 제공된 링크에는 해당 링크가 없습니다.
다음과 같이 사용되는 UserControl을 만들었습니다.
<UtilitiesWPF:FolderEntry Text="{Binding Path=LogFolder}" Description="Folder for log files"/>
xaml 소스는 다음과 같습니다.
<UserControl x:Class="Utilities.WPF.FolderEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel>
<Button Margin="0" Padding="0" DockPanel.Dock="Right" Width="Auto" Click="BrowseFolder">...</Button>
<TextBox Height="Auto" HorizontalAlignment="Stretch" DockPanel.Dock="Right"
Text="{Binding Text, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
</DockPanel>
</UserControl>
코드 숨김
public partial class FolderEntry {
public static DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(FolderEntry), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public static DependencyProperty DescriptionProperty = DependencyProperty.Register("Description", typeof(string), typeof(FolderEntry), new PropertyMetadata(null));
public string Text { get { return GetValue(TextProperty) as string; } set { SetValue(TextProperty, value); }}
public string Description { get { return GetValue(DescriptionProperty) as string; } set { SetValue(DescriptionProperty, value); } }
public FolderEntry() { InitializeComponent(); }
private void BrowseFolder(object sender, RoutedEventArgs e) {
using (FolderBrowserDialog dlg = new FolderBrowserDialog()) {
dlg.Description = Description;
dlg.SelectedPath = Text;
dlg.ShowNewFolderButton = true;
DialogResult result = dlg.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK) {
Text = dlg.SelectedPath;
BindingExpression be = GetBindingExpression(TextProperty);
if (be != null)
be.UpdateSource();
}
}
}
}
be.UpdateSource
가요? 종속성 속성에서 알림을 자동으로 변경해서는 안됩니까?
내가 사용하고 Ookii 대화 상자를 잠시 동안 그리고 WPF를 위해 좋은 작동합니다.
직접 페이지는 다음과 같습니다.
사용자 정의 대화 상자를 만들지 않고 100 % WPF 방식을 선호하고 별도의 DDL, 추가 종속성 또는 오래된 API를 사용하지 않으려는 경우 다른 이름으로 저장 대화 상자를 사용하여 매우 간단한 해킹을 생각해 냈습니다.
사용 지시문이 필요하지 않으므로 아래 코드를 복사하여 붙여 넣을 수 있습니다!
여전히 매우 사용자 친화적이어야하며 대부분의 사람들은 눈치 채지 못할 것입니다.
아이디어는 대화 상자의 제목을 변경하고 파일을 숨기고 결과 파일 이름을 매우 쉽게 해결할 수 있다는 사실에서 비롯됩니다.
확실히 큰 해킹이지만 어쩌면 사용법에 따라 잘 작동 할 것입니다 ...
이 예제에서는 결과 경로를 포함하는 텍스트 상자 객체가 있지만 원하는 경우 관련 줄을 제거하고 반환 값을 사용할 수 있습니다.
// Create a "Save As" dialog for selecting a directory (HACK)
var dialog = new Microsoft.Win32.SaveFileDialog();
dialog.InitialDirectory = textbox.Text; // Use current value for initial dir
dialog.Title = "Select a Directory"; // instead of default "Save As"
dialog.Filter = "Directory|*.this.directory"; // Prevents displaying files
dialog.FileName = "select"; // Filename will then be "select.this.directory"
if (dialog.ShowDialog() == true) {
string path = dialog.FileName;
// Remove fake filename from resulting path
path = path.Replace("\\select.this.directory", "");
path = path.Replace(".this.directory", "");
// If user has changed the filename, create the new directory
if (!System.IO.Directory.Exists(path)) {
System.IO.Directory.CreateDirectory(path);
}
// Our final value is in path
textbox.Text = path;
}
이 핵과 관련된 유일한 문제는 다음과 같습니다.
마이크로 소프트가 엉덩이에서 머리를 빼앗을 경우 공식 WPF 방식을 선호하지만 분명히 할 때까지는 이것이 나의 임시 해결책이다.
디렉터리 대화 상자에서 디렉터리 경로를 얻으려면 먼저 참조 System.Windows.Forms를 추가 한 다음 확인을 클릭 한 다음이 코드를 단추 클릭으로 넣습니다.
var dialog = new FolderBrowserDialog();
dialog.ShowDialog();
folderpathTB.Text = dialog.SelectedPath;
(folderpathTB는 폴더 경로를 넣고 싶어하는 TextBox의 이름입니다. 또는 문자열 변수에도 할당 할 수 있습니다)
string folder = dialog.SelectedPath;
FileName / path를 얻으려면 버튼 클릭으로 간단히 수행하십시오.
FileDialog fileDialog = new OpenFileDialog();
fileDialog.ShowDialog();
folderpathTB.Text = fileDialog.FileName;
(folderpathTB는 파일 경로를 넣고 싶은 TextBox의 이름입니다. 또는 u를 문자열 변수에 할당 할 수도 있습니다)
참고 : 폴더 대화 상자의 경우 System.Windows.Forms.dll을 프로젝트에 추가해야합니다. 그렇지 않으면 작동하지 않습니다.
아래 링크에서 아래 코드를 찾았습니다. 폴더 선택 대화 상자 WPF가 작동했습니다.
using Microsoft.WindowsAPICodePack.Dialogs;
var dlg = new CommonOpenFileDialog();
dlg.Title = "My Title";
dlg.IsFolderPicker = true;
dlg.InitialDirectory = currentDirectory;
dlg.AddToMostRecentlyUsedList = false;
dlg.AllowNonFileSystemItems = false;
dlg.DefaultDirectory = currentDirectory;
dlg.EnsureFileExists = true;
dlg.EnsurePathExists = true;
dlg.EnsureReadOnly = false;
dlg.EnsureValidNames = true;
dlg.Multiselect = false;
dlg.ShowPlacesList = true;
if (dlg.ShowDialog() == CommonFileDialogResult.Ok)
{
var folder = dlg.FileName;
// Do something with selected folder string
}
원하는 것을 달성하는 가장 좋은 방법은 자신 만의 wpf 기반 컨트롤을 만들거나 다른 사람들이 만든 컨트롤을 사용하는 것입니다
. wpf 응용 프로그램에서 winforms 대화 상자를 사용할 때 눈에 띄는 성능 영향이 있기 때문에 (어떤 이유로 든)
이 프로젝트
https://opendialog.codeplex.com/
또는 Nuget을 권장합니다 .
PM> Install-Package OpenDialog
그것은 매우 MVVM 친화적이며 winforms 대화 상자를 감싸지 않습니다.
너겟 패키지에 추가하는 것이 좋습니다.
Install-Package OpenDialog
그런 다음 사용 방법은 다음과 같습니다.
Gat.Controls.OpenDialogView openDialog = new Gat.Controls.OpenDialogView();
Gat.Controls.OpenDialogViewModel vm = (Gat.Controls.OpenDialogViewModel)openDialog.DataContext;
vm.IsDirectoryChooser = true;
vm.Show();
WPFLabel.Text = vm.SelectedFilePath.ToString();
설명서는 다음과 같습니다. http://opendialog.codeplex.com/documentation
파일, 필터가있는 파일, 폴더 등에서 작동
VistaFolderBrowserDialog
는 당신이 원하는 것입니다.Ooki 대화 상자 의 폴더 브라우저 만 원하고 소스 를 다운로드 하지 않으면 폴더 브라우저에 필요한 파일 (힌트 : 7 파일)을 선택하고 .NET 4.5.2에서 올바르게 빌드하십시오. 에 대한 참조를 추가해야했습니다 System.Drawing
. 원래 프로젝트의 참조를 귀하의 참조와 비교하십시오.
어떤 파일을 어떻게 알 수 있습니까? 다른 Visual Studio 인스턴스에서 앱과 Ookii를 엽니 다. 추가 VistaFolderBrowserDialog.cs
앱과 빌드 오류가 사라질 때까지 추가 파일을 보관. Ookii 프로젝트에서 종속성을 찾으십시오-Control- 클릭하십시오.
너무 게으른 경우 필요한 파일은 다음과 같습니다.
NativeMethods.cs
SafeHandles.cs
VistaFolderBrowserDialog.cs
\ Interop
COMGuids.cs
ErrorHelper.cs
ShellComInterfaces.cs
ShellWrapperDefinitions.cs
VistaFolderBrowserDialog.cs
포함하지 않으려면 197 행을 편집하십시오.Resources.Resx
새로운 InvalidOperationException을 던집니다 (Properties.Resources.FolderBrowserDialogNoRootFolder);
throw new InvalidOperationException("Unable to retrieve the root folder.");
앱에 따라 저작권 표시를 앱에 추가하십시오. license.txt
\Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs
160-169 행 의 코드 는 사용할 수있는 예제이지만 WPF this,
에서 제거해야합니다 MessageBox.Show(this,
.
내 컴퓨터에서 작동 [TM]
나는 이것이 오래된 질문이라는 것을 알고 있지만 이것을하는 간단한 방법은 WPF가 제공하고 System.IO.Path.GetDirectory (filename)를 사용하는 FileDialog 옵션을 사용하는 것입니다.
이 답변 중 어느 것도 나를 위해 일하지 않았습니다 (일반적으로 누락 된 참조 또는 그 줄을 따라 뭔가가있었습니다)
그러나 이것은 매우 간단했습니다.
WPF 응용 프로그램에서 FolderBrowserDialog 사용
System.Windows.Forms
이 코드에 대한 참조를 추가 하고 사용하십시오.
var dialog = new System.Windows.Forms.FolderBrowserDialog();
System.Windows.Forms.DialogResult result = dialog.ShowDialog();
누락 된 패키지를 추적 할 필요가 없습니다. 또는 거대한 수업을 추가하십시오
이것은 나에게 새로운 폴더를 만들 수있는 현대적인 폴더 선택기를 제공합니다.
다른 컴퓨터에 배포 할 때의 영향을 아직 보지 못했습니다
WPF에서 이와 같이 smth를 사용할 수 있습니다. 예제 방법을 만들었습니다. 아래를 확인하십시오.
public string getFolderPath()
{
// Create OpenFileDialog
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Multiselect = false;
openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
if (openFileDialog.ShowDialog() == true)
{
System.IO.FileInfo fInfo = new System.IO.FileInfo(openFileDialog.FileName);
return fInfo.DirectoryName;
}
return null;
}