programing

디렉토리 열기 대화상자

mailnote 2023. 4. 26. 23:32
반응형

디렉토리 열기 대화상자

사용자가 내가 생성할 파일이 저장될 디렉토리를 선택하기를 원합니다.나는 WPF에서 내가 사용해야 한다는 것을 알고 있습니다.OpenFileDialogWin32에서 파일을 선택해야 하지만 안타깝게도 대화 상자에서 파일을 선택하지 않고 확인을 클릭하면 파일이 열린 상태로 유지됩니다.사용자가 파일을 선택한 다음 해당 파일이 속한 디렉터리를 파악하기 위해 경로를 제거함으로써 기능을 "해킹"할 수 있지만, 이는 기껏해야 직관적이지 않습니다.전에 이거 본 사람 있어요?

기본 제공 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 4.5+)

  • Windows API Code Pack-Shell:

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

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

다음과 같이 사용되는 사용자 컨트롤을 만들었습니다.

  <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();
            }
        }
    }
 }

답변에서 처럼, 앞답변언바같와이급한서에의,▁as앞이같바,FolderBrowserDialog이 클래스에 사용할 클래스입니다.일부 사람들은 이 대화 상자의 모양과 동작에 대해 (정당한) 우려를 가지고 있습니다.좋은 소식은 NET Core 3.0에서 "현대화"되었다는 것입니다. 따라서 이제 해당 버전 이상을 대상으로 Windows Forms 또는 WPF 앱을 작성하는 사용자에게는 실행 가능한 옵션이 제공됩니다(NET Framework를 계속 사용하는 경우에는 운이 좋지 않습니다).

.NET Core 3.0에서 Windows Forms 사용자 [sic]는 Windows Vista에 도입된 새로운 COM 기반 컨트롤입니다.NET Core 3.0의 FolderBrowserDialog

NET Core WPF 앱에서 참조하려면 프로젝트 파일을 편집하고 다음 행을 추가해야 합니다.

<UseWindowsForms>true</UseWindowsForms>

의 이은기바뒤배수있다치습니 뒤에 할 수 .<UseWPF>원소의

그런 다음 대화 상자를 사용하는 경우입니다.

using System;
using System.Windows.Forms;

...

using var dialog = new FolderBrowserDialog
{
    Description = "Time to select a folder",
    UseDescriptionForTitle = true,
    SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory)
        + Path.DirectorySeparatorChar,
    ShowNewFolderButton = true
};

if (dialog.ShowDialog() == DialogResult.OK)
{
    ...
}

FolderBrowserDialog을 가지고 있습니다.RootFolder"찾아보기가 시작되는 루트 폴더를 설정"하는 속성이지만 제가 설정한 속성은 아무런 차이가 없었습니다.SelectedPath이러한 용도로 사용하기에 더 좋은 속성인 것 같았지만, 후행 백슬래시가 필요합니다.

고또리그.ShowNewFolderButton속성도 무시되는 것 같습니다. 버튼은 항상 표시됩니다.

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

PM> Install-Package Ookii.Dialogs.Wpf

그리고 예제 코드는 아래와 같습니다.

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

사용 방법에 대한 더 많은 정보: https://github.com/augustoproiete/ookii-dialogs-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;
}

이 해킹의 유일한 문제는 다음과 같습니다.

  • Acknowledge 버튼은 여전히 "Select directory"와 같은 것 대신 "Save"라고 표시되지만, mines와 같은 경우에는 디렉토리 선택을 "Save"하여 계속 작동합니다.
  • 입력 필드에는 여전히 "Directory name" 대신 "File name"이라고 표시되지만, 디렉토리는 파일의 일종이라고 할 수 있습니다.
  • 여전히 "Save as type" 드롭다운이 있지만 해당 값이 "Directory(*.this.directory)"로 표시되고 사용자가 다른 항목에 대해 변경할 수 없기 때문에...

대부분의 사람들은 이것들을 눈치채지 못할 것입니다. 하지만 저는 마이크로소프트가 그들의 머리를 빼낼 수 있다면 공식적인 WPF 방식을 사용하는 것을 분명히 선호하지만, 그것이 제 임시방편입니다.

Ookii 대화 상자에는 파일 대신 폴더를 선택하는 대화 상자가 포함되어 있습니다.

Ookii 대화상자 폴더 선택 스크린샷

https://github.com/ookii-dialogs

디렉토리 대화상자가 디렉토리 경로를 가져오려면 먼저 참조 시스템 추가를 선택합니다.창문들.양식을 작성한 다음 해결하고 단추를 클릭하여 이 코드를 입력합니다.

    var dialog = new FolderBrowserDialog();
    dialog.ShowDialog();
    folderpathTB.Text = dialog.SelectedPath;

(폴더 경로)TB는 폴더 경로를 넣거나 문자열 변수에 할당할 수 있는 TextBox 이름입니다.

    string folder = dialog.SelectedPath;

파일 이름/경로를 가져오려면 버튼을 클릭하여 이 작업을 클릭하십시오.

    FileDialog fileDialog = new OpenFileDialog();
    fileDialog.ShowDialog();
    folderpathTB.Text = fileDialog.FileName;

(폴더 경로)TB는 파일 경로를 넣거나 문자열 변수에 할당할 수 있는 TextBox 이름입니다.)

참고: 폴더 대화 상자의 경우 시스템입니다.창문들.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
}

나는 너겟 패키지에 추가할 것을 제안합니다.

  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

파일, 필터가 있는 파일, 폴더 등에 사용 가능

컨트롤을 입니다.
wpf 애플리케이션에서 winforms 대화 상자를 사용할 때 성능에 현저한 영향을 미치기 때문입니다(어떤 이유에서인지).
는 이 합니다.
https://.codeplex.com/https://opendialog.codeplex.com/
Nuget: 또는 Nuget:

PM> Install-Package OpenDialog

매우 MVVM 친화적이며 winforms 대화 상자를 싸고 있지 않습니다.

VistaFolderBrowserDialog당신이 원하는 사람입니다.

Ooki Dialogs에서 폴더 브라우저만 원하는 경우 소스를 다운로드하고 폴더 브라우저에 필요한 파일(힌트: 7개 파일)을 선택하면 에서 올바르게 빌드됩니다.NET 4.5.2.에 대한 참조를 추가해야 했습니다.System.Drawing원본 프로젝트의 참조를 사용자의 참조와 비교합니다.

어떤 파일인지 어떻게 알 수 있습니까?다른 Visual Studio 인스턴스에서 앱과 Ookii를 엽니다.더하다VistaFolderBrowserDialog.cs앱에 파일을 추가하고 빌드 오류가 사라질 때까지 파일을 계속 추가합니다.Ookii 프로젝트에서 종속성을 찾을 수 있습니다. - 제어 - 원본(pun 의도)으로 되돌리려는 종속성을 클릭합니다.

너무 귀찮으면 필요한 파일이 여기 있습니다...

NativeMethods.cs
SafeHandles.cs
VistaFolderBrowserDialog.cs
\ Interop
   COMGuids.cs
   ErrorHelper.cs
   ShellComInterfaces.cs
   ShellWrapperDefinitions.cs

197행 편집행VistaFolderBrowserDialog.cs당신이 그들의 것을 포함하고 싶지 않다면.Resources.Resx

새 유효하지 않은 작업 던지기예외(속성).자원.폴더BrowserDialogRootFolder);

throw new InvalidOperationException("Unable to retrieve the root folder.");

그들의 저작권 고지를 당신의 앱에 추가합니다.license.txt

에 있는 \Ookii.Dialogs.Wpf.Sample\MainWindow.xaml.cs수 160-1600 라인은 .this,MessageBox.Show(this,WPF »

내 시스템에서 작동 [TM]

이러한 답변 중 어느 것도 저에게 도움이 되지 않았습니다(일반적으로 참조가 누락되었거나 해당 라인을 따라 무언가가 있었습니다).

하지만 이것은 아주 간단하게 이루어졌습니다.

WPF 응용 프로그램에서 FolderBrowserDialog 사용

에 대한 참조를 합니다.System.Windows.Forms다음 코드를 사용합니다.

  var dialog = new System.Windows.Forms.FolderBrowserDialog();
  System.Windows.Forms.DialogResult result = dialog.ShowDialog();

누락된 패키지를 추적할 필요가 없습니다.또는 방대한 클래스 추가

새 폴더를 만들 수 있는 최신 폴더 선택기를 제공합니다.

다른 시스템에 배포할 때의 영향을 아직 확인하지 못했습니다.

오래된 질문인 것은 알지만 WPF에서 제공하는 FileDialog 옵션을 사용하고 시스템을 사용하는 것이 간단한 방법입니다.IO.경로.디렉터리(파일 이름)를 가져옵니다.

당신은 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;           
       }

마이크로소프트사인 것 같습니다.Win32 .NET 라이브러리는 폴더 선택(파일만)을 지원하지 않으므로 WPF(2022년 7월 기준)에서 운이 없습니다.저는 지금 가장 좋은 옵션이 WPF: https://github.com/ookii-dialogs/ookii-dialogs-wpf 의 Ookii라고 생각합니다.WPF에서 마이크로소프트 지원을 제외한 예상대로 잘 작동합니다.당신은 그것을 NuGet 패키지로 받을 수 있습니다.XAML 보기 뒤의 코드:

public partial class ExportRegionView : UserControl
{
    public ExportRegionView()
    {
        InitializeComponent();
    }
    private void SavePath(object sender, RoutedEventArgs e)
    {
        var dialog = new Ookii.Dialogs.Wpf.VistaFolderBrowserDialog();
        dialog.Description = "SIPAS Export Folder";
        dialog.UseDescriptionForTitle = true;
        if (dialog.ShowDialog().GetValueOrDefault())
        {
            ExportPath.Text = dialog.SelectedPath;
        }
    }
}

XAML: <Button Grid.Row="1" Grid.Column="3" Style="{DynamicResource Esri_Button}" Click="SavePath" Margin="5,5,5,5">Path</Button>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Gearplay
{
    /// <summary>
    /// Логика взаимодействия для OpenFolderBrows.xaml
    /// </summary>
    public partial class OpenFolderBrows : Page
    {
        internal string SelectedFolderPath { get; set; }
        public OpenFolderBrows()
        {
            InitializeComponent();
            Selectedpath();
            InputLogicalPathCollection();
             
        }

        internal void Selectedpath()
        {
            Browser.Navigate(@"C:\");
            
            Browser.Navigated += Browser_Navigated;
        }

        private void Browser_Navigated(object sender, NavigationEventArgs e)
        {
            SelectedFolderPath = e.Uri.AbsolutePath.ToString();
            //MessageBox.Show(SelectedFolderPath);
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
          
           
        }
        
        string [] testing { get; set; }
        private void InputLogicalPathCollection()
        {            // add Menu items for Cotrol 
            string[] DirectoryCollection_Path = Environment.GetLogicalDrives(); // Get Local Drives
            testing = new string[DirectoryCollection_Path.Length];
            //MessageBox.Show(DirectoryCollection_Path[0].ToString());
            MenuItem[]  menuItems = new MenuItem[DirectoryCollection_Path.Length]; // Create Empty Collection
            for(int i=0;i<menuItems.Length;i++)
            {
                // Create collection depend how much logical drives 
                menuItems[i] = new MenuItem();
                menuItems[i].Header = DirectoryCollection_Path[i];
                menuItems[i].Name = DirectoryCollection_Path[i].Substring(0,DirectoryCollection_Path.Length-1);
                DirectoryCollection.Items.Add(menuItems[i]);
                menuItems[i].Click += OpenFolderBrows_Click;
                testing[i]= DirectoryCollection_Path[i].Substring(0, DirectoryCollection_Path.Length - 1);
            }

            

        }
        
        private void OpenFolderBrows_Click(object sender, RoutedEventArgs e)
        {

            foreach (string str in testing)
            {
                if (e.OriginalSource.ToString().Contains("Header:"+str)) // Navigate to Local drive
                {
                    Browser.Navigate(str + @":\");
                   
                }


            }


        }

        private void Goback_Click(object sender, RoutedEventArgs e)
        {// Go Back
            try
            {
                Browser.GoBack();
            }catch(Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void Goforward_Click(object sender, RoutedEventArgs e)
        { //Go Forward
            try
            {
                Browser.GoForward();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void FolderForSave_Click(object sender, RoutedEventArgs e)
        {
            // Separate Click For Go Back same As Close App With send string var to Main Window ( Main class etc.) 
            this.NavigationService.GoBack();
        }
    }
}

언급URL : https://stackoverflow.com/questions/1922204/open-directory-dialog

반응형