निर्देशिका निर्देशिका खोलें


274

मैं चाहता हूं कि उपयोगकर्ता एक निर्देशिका का चयन करें जहां एक फ़ाइल जिसे मैं फिर उत्पन्न करूंगा, सहेजा जाएगा। मुझे पता है कि WPF में मुझे OpenFileDialogWin32 से उपयोग करना चाहिए , लेकिन दुर्भाग्य से संवाद के लिए फ़ाइल (नों) का चयन करने की आवश्यकता होती है - यह खुला रहता है अगर मैं बस एक को चुनने के बिना ठीक क्लिक करता हूं। मैं उपयोगकर्ता को एक फ़ाइल लेने की सुविधा देकर कार्यक्षमता को "हैक" कर सकता हूं और फिर यह पता लगाने के लिए कि यह किस निर्देशिका का है, लेकिन यह सबसे अच्छा है। क्या किसी ने इससे पहले ऐसा देखा है?



यहां एक नज़र डालें stackoverflow.com/questions/4007882/select-folder-dialog-wpf
डेवलपर

जवाबों:


406

आप इसके लिए अंतर्निहित FolderBrowserDialog वर्ग का उपयोग कर सकते हैं । बुरा मत मानना ​​कि यह System.Windows.Formsनामस्थान में है।

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

यदि आप चाहते हैं कि विंडो कुछ WPF विंडो पर मोडल हो, तो प्रश्न देखें कि WPF एप्लिकेशन से FolderBrowserDialog का उपयोग कैसे करें


संपादित करें: यदि आप सादे, बदसूरत विंडोज फॉर्म FolderBrowserDialog की तुलना में कुछ अधिक फैंसी चाहते हैं, तो कुछ विकल्प हैं जो आपको इसके बजाय विस्टा संवाद का उपयोग करने की अनुमति देते हैं:

  • तृतीय-पक्ष पुस्तकालय, जैसे कि Ookii संवाद (.NET 3.5)
  • Windows API कोड पैक-शैल :

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

    ध्यान दें कि यह संवाद विंडोज विस्टा से पुराने ऑपरेटिंग सिस्टम पर उपलब्ध नहीं है, इसलिए CommonFileDialog.IsPlatformSupportedपहले जांच लें ।


78
ध्यान दें कि यह एक भयानक संवाद है। आप इसमें कोई पथ कॉपी और पेस्ट नहीं कर सकते, और यह पसंदीदा फ़ोल्डरों का समर्थन नहीं करता है। कुल मिलाकर, मैं इसे 5 में से 0 देता हूं और किसी को भी इसका उपयोग करने की सलाह नहीं देता। सिवाय इसके कि कोई बेहतर विकल्प नहीं था जब तक कि विंडोज विस्टा ज्यादा बेहतर फोल्डर डायलॉग के साथ नहीं आया । कर रहे हैं अच्छा मुक्त पुस्तकालयों कि पर विस्टा + अच्छा संवाद, और XP पर बुरा दिखा।
रोमन स्टार्कोव

70
फिर भी, WPF एक महान OpenFileDialog की पेशकश क्यों नहीं करता है, लेकिन OpenFolderDialog नहीं है? यह थोड़ा अजीब नहीं है? यहां WPF की कमी क्यों है? क्या WPF में इस संवाद के लिए एक वर्ग जोड़ने की कोई योजना है?
पॉल-सेबेस्टियन मैनोल

14
यह मत भूलो कि FolderBrowserDialog डिस्पोजेबल है।
लॉसमनोस

9
ध्यान दें कि उपयोग करने के क्रम में CommonOpenFileDialogसे WindowsAPICodePackआप की जरूरत है Install-Package WindowsAPICodePack-Shell। उत्तर में दिए गए लिंक की सूची नहीं है।
निकोला नोवाक

5
"प्रकार या नाम स्थान CommonOpenFileDialog नहीं मिल सका"। यह 2017 है और मैं एक फ़ोल्डर
Nick.McD मत्स्य

46

मैंने एक 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();
            }
        }
    }
 }

1
+1, UserControl लिखने के तरीके पर अच्छा उदाहरण। एक प्रश्न: आपको आवश्यकता क्यों है be.UpdateSource? क्या निर्भरता गुणों में सूचनाएं स्वचालित नहीं होनी चाहिए?
Heinzi

4
आप अपडेट को फायर करने के लिए बाइंडिंग में निर्दिष्ट कर सकते हैं। डिफ़ॉल्ट रूप से यह लॉस्टफोकस पर है, लेकिन आप इसे प्रॉपर्टीचेंज पर अपडेट को भी बता सकते हैं।
एलेक्जेंड्रा

3
फिर हर कीस्ट्रोक के लिए बाइंडिंग को अपडेट किया जाएगा। यदि उपयोगकर्ता अद्यतन पर किसी प्रकार का सत्यापन करता है (जैसे Directory.Exist) तो यह समस्याएँ पैदा कर सकता है।
एड्रियनम


10

Ookii फ़ोल्डर संवाद Nuget पर पाया जा सकता है।

PM> Install-Package Ookii.Dialogs

और, उदाहरण कोड नीचे है।

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

tnx आपका रास्ता सबसे छोटा था
एहसान wwe

8

उन लोगों के लिए जो एक कस्टम संवाद नहीं बनाना चाहते हैं, लेकिन फिर भी 100% WPF तरीका पसंद करते हैं और अलग DDLs, अतिरिक्त निर्भरता या पुराने APIs का उपयोग नहीं करना चाहते हैं, मैं Save As डायलॉग का उपयोग करके बहुत ही सरल हैक के साथ आया हूं।

आवश्यक निर्देश का उपयोग नहीं, आप बस नीचे दिए गए कोड को कॉपी-पेस्ट कर सकते हैं!

यह अभी भी बहुत उपयोगकर्ता के अनुकूल होना चाहिए और अधिकांश लोग कभी नोटिस नहीं करेंगे।

विचार इस तथ्य से आता है कि हम उस संवाद का शीर्षक बदल सकते हैं, फ़ाइलें छिपा सकते हैं, और परिणामी फ़ाइल नाम के आसपास बहुत आसानी से काम कर सकते हैं।

यह सुनिश्चित करने के लिए एक बड़ी हैक है, लेकिन शायद यह आपके उपयोग के लिए ठीक काम करेगा ...

इस उदाहरण में मेरे पास परिणामी पथ को शामिल करने के लिए एक टेक्स्टबॉक्स ऑब्जेक्ट है, लेकिन आप संबंधित लाइनों को हटा सकते हैं और यदि आप चाहें तो रिटर्न वैल्यू का उपयोग कर सकते हैं ...

// 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;
}

इस हैक के साथ केवल मुद्दे हैं:

  • पावती बटन अभी भी "सेलेक्ट डाइरेक्टरी" जैसी किसी चीज़ के बजाय "सेव" कहता है, लेकिन माइंस जैसे मामले में मैं डाइरेक्टरी सिलेक्शन को "सेव" करता हूँ इसलिए यह अभी भी काम करता है ...
  • इनपुट फ़ील्ड अभी भी "निर्देशिका नाम" के बजाय "फ़ाइल नाम" कहती है, लेकिन हम कह सकते हैं कि एक निर्देशिका एक प्रकार की फ़ाइल है ...
  • अभी भी "Save as type" ड्रॉपडाउन है, लेकिन इसका मान "निर्देशिका (* .this.directory)" कहता है, और उपयोगकर्ता इसे किसी और चीज़ के लिए नहीं बदल सकता है, मेरे लिए काम करता है ...

अधिकांश लोग इन पर ध्यान नहीं देंगे, हालांकि मैं निश्चित रूप से एक आधिकारिक WPF तरीके का उपयोग करना पसंद करूंगा यदि Microsoft उनके सिर को अपने गधे से बाहर निकाल देगा, लेकिन जब तक वे ऐसा नहीं करते, यह मेरा अस्थायी सुधार है।


1
यह मस्त था। हैरानी इस बात की है कि किसी और ने ऐसा करने की कोशिश नहीं की। NuGet पैकेज बेशक बेहतर है, लेकिन NuGet WindowsAPICodePack के बिना यह किसी भी नए पैकेज / संदर्भों को जोड़े बिना फ़ोल्डर का चयन करने की क्षमता को छिपाने का एक शानदार तरीका है।
कोड नौिस

7

निर्देशिका पथ प्राप्त करने के लिए निर्देशिका संवाद के लिए, पहले संदर्भ System.Windows.Forms जोड़ें, और उसके बाद हल करें, और फिर इस कोड को एक बटन क्लिक में डालें।

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

(folderpTTB टेक्स्टबॉक्स का नाम है जहां मैंने फ़ोल्डर पथ रखा है, या आप इसे स्ट्रिंग चर पर भी निर्दिष्ट कर सकते हैं)

    string folder = dialog.SelectedPath;

और यदि आप FileName / path प्राप्त करते हैं, तो बस बटन क्लिक पर ऐसा करें

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

(folderpTTB टेक्स्टबॉक्स का नाम है जहां मैंने फ़ाइल पथ रखा है, या आप इसे एक स्ट्रिंग चर में भी असाइन कर सकते हैं)

नोट: फ़ोल्डर डायलॉग के लिए, System.Windows.Forms.dll को प्रोजेक्ट में जोड़ा जाना चाहिए, अन्यथा यह काम नहीं करेगा।


आपके उत्तर के लिए धन्यवाद, लेकिन यह दृष्टिकोण पहले ही ऊपर @Hininzi द्वारा समझाया गया है।
एलेक्जेंड्रा

5

मुझे नीचे दिए गए लिंक पर नीचे का कोड मिला ... और इसने फ़ोल्डर डायलॉग 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
}

4

जो आप चाहते हैं उसे प्राप्त करने का सबसे अच्छा तरीका है कि आप अपना wpf आधारित नियंत्रण बनाएं, या एक का उपयोग करें जो अन्य लोगों द्वारा बनाया गया था
क्यों? क्योंकि wpf एप्लिकेशन में winforms संवाद का उपयोग करते समय एक ध्यान देने योग्य प्रदर्शन प्रभाव होगा (किसी कारण से)
मैं इस परियोजना की सिफारिश करता हूं
https://opendialog.codeplex.com/
या Nuget:

PM> Install-Package OpenDialog

यह बहुत ही MVVM फ्रेंडली है और यह विनफॉर्म डायलॉग को रैप नहीं कर रहा है


3

मैं सुझाव दूंगा, डला पैकेज में जोड़ने के लिए:

  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

फ़ाइलें, फ़िल्टर, फ़ोल्डर, आदि के साथ फ़ाइलों के लिए काम करता है


2

Ookii VistaFolderBrowserDialogएक आप चाहते हैं।

अगर आप केवल Ooki Dialogs से Folder Browser चाहते हैं और इसके अलावा कुछ भी नहीं है तो Source , cherry-pick को उन फ़ाइलों को डाउनलोड करें जिनकी आपको Folder Browser (hint: 7 files) के लिए ज़रूरत है और यह .NET 4.5.2 में ठीक बनाता है। मुझे एक संदर्भ जोड़ना था System.Drawing। मूल परियोजना के संदर्भों की तुलना आप से करें।

आप किस फाइल का पता लगाते हैं? अपने ऐप और Ookii को अलग-अलग विज़ुअल स्टूडियो इंस्टेंस में खोलें। VistaFolderBrowserDialog.csअपने ऐप में जोड़ें और तब तक फाइलें जोड़ते रहें जब तक बिल्ड एरर दूर न हो जाए। आपको Ookii परियोजना में निर्भरताएं मिलती हैं - जिस पर आप वापस अपने स्रोत (इच्छित उद्देश्य) का पालन करना चाहते हैं, उसे नियंत्रित करें।

यहां उन फ़ाइलों की आवश्यकता है जिन्हें आप करने के लिए बहुत आलसी हैं ...

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 एक उदाहरण आप उपयोग कर सकते है, लेकिन आप को दूर करने की आवश्यकता होगी this,से MessageBox.Show(this,WPF के लिए।

मेरी मशीन पर काम करता है [TM]


2

मुझे पता है कि यह एक पुराना प्रश्न है, लेकिन ऐसा करने का एक सरल तरीका WPF द्वारा प्रदान की गई FileDialog विकल्प और System.IO.Path.GetDirectory (फ़ाइल नाम) का उपयोग करना है।


लेकिन तब उपयोगकर्ता को एक फ़ाइल चुननी होगी, भले ही उसे एक फ़ोल्डर चुनने के लिए कहा जाए। एक अनुभवहीन उपयोगकर्ता इस बिंदु पर हेल्पडेस्क को कॉल कर सकता है, यह पूछते हुए कि जब उसे एक फ़ोल्डर चुनना है तो उसे फाइल क्यों
चुननी है

0

इनमें से किसी भी उत्तर ने मेरे लिए काम नहीं किया (आमतौर पर उन लाइनों के साथ एक लापता संदर्भ या कुछ और था)

लेकिन यह काफी बस किया:

WPF अनुप्रयोग में FolderBrowserDialog का उपयोग करना

System.Windows.Formsइस कोड का संदर्भ और उपयोग करें:

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

लापता पैकेज को ट्रैक करने की आवश्यकता नहीं है। या विशाल वर्ग जोड़ें

यह मुझे एक आधुनिक फ़ोल्डर चयनकर्ता देता है जो आपको एक नया फ़ोल्डर बनाने की अनुमति देता है

अन्य मशीनों पर तैनात होने पर मुझे अभी तक प्रभाव नहीं दिख रहा है


0

आप 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;           
       }

1
इसके लिए उपयोगकर्ता को फ़ोल्डर से फ़ाइल का चयन करना होगा। यदि फ़ोल्डर खाली है तो आप अपने फ़ोल्डर का चयन नहीं कर सकते।
अलेक्जेंड्रू डिकु

हां, मैं समझता हूं कि, यह कुछ प्रकार का वर्कअराउंड है, न कि इस मुद्दे का सही समाधान।
koberone
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.