[wpf] 디렉토리 열기 대화 상자

사용자가 생성 할 파일이 저장 될 디렉토리를 선택하기를 원합니다. 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 대화 상자를 사용할 수있는 몇 가지 대안이 있습니다.

  • Ookii 대화 상자 와 같은 타사 라이브러리 (.NET 3.5)
  • 윈도우 API 코드 팩 – 쉘 :

    using Microsoft.WindowsAPICodePack.Dialogs;
    
    ...
    
    var dialog = new CommonOpenFileDialog();
    dialog.IsFolderPicker = true;
    CommonFileDialogResult result = dialog.ShowDialog();

    이 대화 상자는 Windows Vista 이전의 운영 체제에서는 사용할 수 없으므로 CommonFileDialog.IsPlatformSupported먼저 확인하십시오 .


답변

다음과 같이 사용되는 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();
            }
        }
    }
 }


답변

내가 사용하고 Ookii 대화 상자를 잠시 동안 그리고 WPF를 위해 좋은 작동합니다.

직접 페이지는 다음과 같습니다.

http://www.ookii.org/Blog/new_download_ookiidialogs


답변

Ookii 폴더 대화 상자는 Nuget에서 찾을 수 있습니다.

PM> Install-Package Ookii.Dialogs

그리고 예제 코드는 다음과 같습니다.

var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
if (dialog.ShowDialog(this).GetValueOrDefault())
{
    textBoxFolderPath.Text = dialog.SelectedPath;
}


답변

사용자 정의 대화 상자를 만들지 않고 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;
}

이 핵과 관련된 유일한 문제는 다음과 같습니다.

  • 승인 버튼은 여전히 ​​”디렉토리 선택”과 같은 대신 “저장”이라고 표시되지만 광산과 같은 경우 디렉토리 선택을 “저장”하므로 여전히 작동합니다 …
  • 입력 필드에는 여전히 “디렉토리 이름”대신 “파일 이름”이 표시되지만 디렉토리는 파일 유형이라고 말할 수 있습니다.
  • 여전히 “유형으로 저장”드롭 다운이 있지만 그 값에 “디렉토리 (* .this.directory)”라고 표시되어 있으며 사용자가 다른 것으로이를 변경할 수 없습니다.

마이크로 소프트가 엉덩이에서 머리를 빼앗을 경우 공식 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
}