आप फ़ोल्डर्स का चयन करने के लिए OpenFileDialog को कैसे कॉन्फ़िगर करते हैं?


251

VS .NET में, जब आप किसी प्रोजेक्ट के लिए एक फ़ोल्डर का चयन कर रहे होते हैं, तो OpenFileDialog या SaveFileDialog जैसा दिखने वाला एक संवाद प्रदर्शित होता है, लेकिन इसे केवल फ़ोल्डर को स्वीकार करने के लिए सेट किया जाता है। जब से मैंने यह देखा है मैं यह जानना चाहता हूं कि यह कैसे हुआ है। मुझे FolderBrowserDialog की जानकारी है, लेकिन मुझे वह डायलॉग कभी पसंद नहीं आया। यह बहुत छोटा है और मुझे एक रास्ता टाइप करने में सक्षम होने का फायदा नहीं उठाने देता।

मैं अब तक लगभग निश्चित हूं। .NET से ऐसा करने का कोई तरीका नहीं है, लेकिन मैं बस उत्सुक हूं कि आप इसे अनवांटेड कोड से भी कैसे करते हैं। स्क्रैच से संवाद को पूरी तरह से फिर से लागू करने के लिए, आप इस व्यवहार के लिए संवाद को कैसे संशोधित करते हैं?

मैं यह भी बताना चाहूंगा कि मुझे FolderBrowserDialog की जानकारी है, लेकिन कभी-कभी मैं इसका उपयोग करना पसंद नहीं करता, इसके अलावा वास्तव में जिज्ञासु होना कि इस तरीके से संवाद कैसे कॉन्फ़िगर किया जाए। मुझे सिर्फ FolderBrowserDialog का उपयोग करने के लिए कहने से मुझे लगातार UI अनुभव बनाए रखने में मदद मिलती है, लेकिन यह मेरी जिज्ञासा को संतुष्ट नहीं करता है, इसलिए यह उत्तर के रूप में नहीं गिना जाएगा।

यह एक विस्टा-विशिष्ट चीज भी नहीं है; मैं इस संवाद को VS .NET 2003 से देख रहा हूं, इसलिए यह Win2k और WinXP में उल्लेखनीय है। यह "मैं इस प्रश्न को करने का उचित तरीका जानना चाहता हूं" से कम है और "मैं इस बारे में उत्सुक हूं क्योंकि मैं पहली बार इसे वीएस 2003 में करना चाहता था" सवाल। मैं समझता हूं कि विस्टा के फ़ाइल संवाद में ऐसा करने का विकल्प है, लेकिन यह XP में काम कर रहा है, इसलिए मुझे पता है कि उन्होंने इसे काम करने के लिए कुछ किया है । विस्टा-विशिष्ट उत्तर उत्तर नहीं हैं, क्योंकि विस्टा प्रश्न के संदर्भ में मौजूद नहीं है।

अद्यतन: मैं स्कॉट विस्निवस्की के उत्तर को स्वीकार कर रहा हूं क्योंकि यह एक काम करने वाले नमूने के साथ आता है, लेकिन मुझे लगता है कि सर्ज संवाद अनुकूलन की ओर इशारा करने के लिए श्रेय का हकदार है (जो कि .NET से बुरा है लेकिन यह काम करता है ) और मार्क रैनसम को पता लगाने के लिए कि एमएस शायद इस कार्य के लिए एक कस्टम संवाद रोल किया गया।


7
कोडप्रोजेक्ट codeproject.com/Articles/44914/… से एक सरल उपाय। [दोनों फ़ाइलों और फ़ोल्डरों का चयन करने के लिए OpenFileDialog प्राप्त करने की कुंजी है, ValidateNames और CheckFileExists गुणों को गलत पर सेट करना है। और यह सुनिश्चित करने के लिए कुछ विशेष कीवर्ड पर फ़ाइलनाम सेट करें कि फ़ोल्डर चयनित हो जाएं (डायल.फाइलनेम = "फ़ोल्डर चयन";)।]
रिजू

3
इसे एक उत्तर के रूप में प्रस्तुत करें, इसने मेरी परियोजना के लिए काम किया।
CigarDoug

@Riju अनुगामी अवधि के साथ dialog.FileName = "Folder Selection"माना जाता है dialog.FileName = "Folder Selection."? वैसे भी मैं इसे "ओपन" के दूसरे क्लिक पर पावरशेल में काम करने के लिए नहीं कर सकता। यह कहता रहता है कि फ़ाइल नहीं मिली, भले ही CheckFileExists कथित रूप से गलत है
कॉमरेडजोकूल

nvm, पावरफुल में सेटिंग के dialog.CheckFileExists = 0बजाय गलत ने मेरे मुद्दे को हल किया
कॉमरेडजोकूल

क्या आपने WPF के लिए Ookii Dialogs आज़माया है ?
सी। ऑगस्टो प्रोएटी

जवाबों:


57

मेरे पास एक डायलॉग है जिसे मैंने OpenFileOrFolder डायलॉग लिखा है जो आपको एक फोल्डर या फाइल खोलने की अनुमति देता है।

यदि आप इसके AcceptFiles मान को गलत पर सेट करते हैं, तो यह केवल स्वीकार फ़ोल्डर मोड में संचालित होता है।

आप यहां GitHub से स्रोत डाउनलोड कर सकते हैं


4
बहुत दिलचस्प है, और निश्चित रूप से उतना ही जटिल है जितना मुझे लगा था। इसे एनोटेट करने और यह क्या करता है की ओर इशारा करते हुए कोई भी मौका? अन्य टिप्पणियों के साथ यह मुझे विश्वास दिलाता है कि एमएस शायद केवल अपने स्वयं के संवाद को लुढ़का।
ओवेनपे

1
आपके समाधान का निर्माण करते समय मुझे निम्न त्रुटि मिलती है ... दुर्भाग्य से मेरी शक्तियों में से एक में सी + + ... त्रुटि 1 नहीं खोल सकता फ़ाइल 'afxres.h' शामिल है।
इग्नासियो सोलर गार्सिया

1
@SoMoS, और अन्य समान समस्या: फ़ाइल में WindowsFormsApplication1.csproj पंक्ति 100 को संपादित करें ताकि यह आपके सेटअप से मेल खाए। मेरे मामले में मुझे "9.0" को "10.0" (दो बार) और "(x86)" (दो बार) को हटाना पड़ा।
RenniePet

2
मैंने कोड (ज़िप) डाउनलोड किया और .h (C) फ़ाइल को पाया, और त्रुटि के साथ संकलित किया जैसे कि फ़ाइल 'sal.h' शामिल नहीं हो सकती।
लेई यांग

2
यह समाधान VS2010 और VS2017 पर भी काम नहीं करता है!
अलेक्स_

49

आप FolderBrowserDialogEx का उपयोग कर सकते हैं - अंतर्निहित FolderBrowserDialog का पुन: प्रयोज्य व्युत्पन्न। यह आपको एक मार्ग में टाइप करने की अनुमति देता है, यहां तक ​​कि एक UNC पथ भी। आप इसके साथ कंप्यूटर या प्रिंटर के लिए भी ब्राउज़ कर सकते हैं। बिल्ट-इन FBD की तरह ही काम करता है, लेकिन ... बेहतर है।

(EDIT: मुझे यह इंगित करना चाहिए कि यह संवाद फ़ाइलों या फ़ोल्डरों का चयन करने के लिए सेट किया जा सकता है।)

पूर्ण स्रोत कोड (एक छोटा C # मॉड्यूल)। नि: शुल्क। एमएस-पब्लिक लाइसेंस।

इसका उपयोग करने के लिए कोड:

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

7
क्षमा करें यदि मैंने नाराज किया है, तो यह केवल एक प्रश्न पूछने और "मुझे यह विशिष्ट चीज चाहिए, इन अन्य चीजों को नहीं" कहना निराशाजनक है और लोगों ने हंसते हुए न मांगी गई चीज़ का सुझाव दिया है। मुझे एक फाइल ब्राउजर डायलॉग चाहिए था, फोल्डर ब्राउजर डायलॉग नहीं।
OwenP

15
जिस तरह से सवाल किया जाता है, वह मुझे लगता है जैसे यह एक फ़ोल्डर पिकर संवाद के लिए पूछ रहा है - क्या यह मामला नहीं है? वैसे भी, यह वही है जो मैं देख रहा था +1
टिम

निश्चित रूप से अब तक का सबसे अच्छा जवाब
वासिल पोपोव

1
यह तथ्य नहीं बदलता है, कि उत्तर अभी भी केवल लिंक का उत्तर है। किसी ऑफ-साइट संसाधन पर होस्ट किए गए कोड का उपयोग करना मददगार साबित होता है, जब वह लिंक भी अस्थायी या स्थायी रूप से अनुपलब्ध हो जाता है। एक कारण के लिए नियम हैं, और यह योगदान उन नियमों के विरोध में है।
IInspectable

1
मैंने इस उत्तर को देखा , और यह स्पष्ट रूप से एक ऑफ-साइट संसाधन का संदर्भ नहीं देता है। तो "हर दूसरे जवाब" स्पष्ट रूप से गलत है। यदि आपको लगता है कि मैं ओवररिएक्ट कर रहा हूं, तो शायद आपको नियमों पर चर्चा करने के लिए मेटा पर एक मुद्दा उठाना चाहिए। मैं नहीं करूंगा मैं बस उन्हें लागू करूंगा।
IInspectable

48

विंडोज एपीआई कोड पैक है। यह CommonOpenFileDialogवर्ग ( Microsoft.WindowsAPICodePack.Dialogsनाम स्थान में) सहित शेल से संबंधित सामान का एक बहुत कुछ मिला है । यह एकदम सही समाधान है - केवल खुले फ़ोल्डरों के साथ खुला संवाद।

इसका उपयोग कैसे करना है, इसका एक उदाहरण इस प्रकार है:

CommonOpenFileDialog cofd = new CommonOpenFileDialog();
cofd.IsFolderPicker = true;
cofd.ShowDialog();

दुर्भाग्यवश Microsoft अब इस पैकेज को शिप नहीं करता है, लेकिन कई लोगों ने अनौपचारिक रूप से न्यूर्जेट में बायनेरिज़ अपलोड किए हैं। एक उदाहरण यहां पाया जा सकता है । यह पैकेज केवल शेल-विशिष्ट सामान है। क्या आपको इसकी आवश्यकता है, उसी उपयोगकर्ता के पास कई अन्य पैकेज हैं जो मूल पैकेज में मौजूद अधिक कार्यक्षमता प्रदान करते हैं।


1
मुझे पता नहीं था कि यह विंडोज एपीआई कोड पैक में है - इसे इंगित करने के लिए धन्यवाद।
पैट्रिक क्लग सेप

10
CommonOpenFileDialog क्लास केवल Windows Vista या उसके बाद के संस्करण पर मौजूद है, इसलिए पुराने ऑपरेटिंग सिस्टम पर एक अपवाद फेंक देगा
राहेल

1
क्या आप कृपया बता सकते हैं कि विंडोज एपीआई कोड पैक को कैसे देखें?
जेफ

1
आर्काइव गैलरी को सेवानिवृत्त कर दिया गया है। , या इसलिए लिंक कहता है .. क्या यह इसके लिए नई जगह हो सकती है?
डिफ़ॉल्ट

3
वैसे, CommonOpenFileDialog वर्ग Microsoft.WindowsAPICodePack.Dialogs नामस्थान में है (मुझे इसे खोजने में कुछ समय लगा)।
मुर्गी

35

Ookii.Dialogs पैकेज नई (विस्टा शैली) के चारों ओर एक कामयाब आवरण ब्राउज़र संवाद फ़ोल्डर में शामिल है। यह पुराने ऑपरेटिंग सिस्टम पर इनायत से नीचा दिखाता है।


2
कूल, यह बीएसडी-शैली-लाइसेंस खुला स्रोत है!
रोमन स्टार्कोव

7
एकमात्र समस्या यह है, मैं एक लक्ष्य के रूप में .net फ्रेमवर्क क्लाइंट प्रोफाइल का उपयोग करने नहीं दूंगा।
कुगेल

2
बहुत अच्छा उपाय है। यह मेरे विचार में सबसे अच्छा जवाब है। बिल्कुल वही जो मैं 3 साल से खोज रहा था।
शमूएल

1
इस समाधान के साथ एक और समस्या: यह उपयोगकर्ता को एक गैर-मौजूद पथ को पेस्ट करने की अनुमति नहीं देता है। एक मामूली, तुलनात्मक रूप से, लेकिन अभी भी एक दया।
रोमन स्टार्कोव

1
उन लोगों के लिए सबसे अच्छा व्यावहारिक उत्तर जो एक OpenFileDialog-स्टाइल फ़ोल्डर संवाद चाहते हैं ।
एक्वा

27

उसके लिए FolderBrowserDialog का उपयोग करना बेहतर है।

using (FolderBrowserDialog dlg = new FolderBrowserDialog())
{
    dlg.Description = "Select a folder";
    if (dlg.ShowDialog() == DialogResult.OK)
    {
        MessageBox.Show("You selected: " + dlg.SelectedPath);
    }
}

9
मुझे पता है कि FolderBrowserDialog का उपयोग करना बेहतर है। मैं उत्सुक हूं कि यह परवाह किए बिना कैसे किया गया। FolderBrowserDialog वैसे भी कई तरह से बदबू मारता है; यहां तक ​​कि विस्टा में यह बार नहीं है। मजेदार है कि कैसे बेहतर है अगर MS ने इसे अब तक 3 VS संस्करणों में टाला है।
ओवेनपे

24
FolderBrowserDialog में कई प्रयोज्य मुद्दे हैं। मैं वास्तव में इसे किसी एप्लिकेशन में डालने पर विचार नहीं करूंगा। एक संवाद के लिए मेरी पोस्ट देखें जिसमें बहुत बेहतर प्रयोज्यता है
स्कॉट विस्निव्स्की

6
FolderBrowserDialog निम्न की अनुमति नहीं देता है: - नीचे पाठ क्षेत्र में पूर्ण पथ टाइप / पेस्ट करें - विस्टा पर "पसंदीदा लिंक" बार का उपयोग करें
decasteljau

89
FolderBrowserDialog UI का वास्तव में भयानक बिट है।
मैकेनेर

32
गंभीरता से, लोग, कृपया इस कष्टप्रद संवाद को अपने अनुप्रयोगों में डालना बंद करें। यह बहुत बुरा यूआई है जैसा कि पहले की टिप्पणियों द्वारा हाइलाइट किया गया था।
रोमन स्टार्कोव

23

खोज के घंटे के बाद मैंने पाया इस उत्तर से leetNightShade को एक काम कर समाधान

तीन चीजें हैं जो मेरा मानना ​​है कि इस समाधान को अन्य सभी की तुलना में बहुत बेहतर बनाता है।

  1. यह उपयोग करने के लिए सरल है। इसके लिए केवल आपको अपनी परियोजना में दो फाइलें (जो किसी भी तरह संयुक्त की जा सकती हैं) शामिल हैं।
  2. XP या पुराने सिस्टम पर उपयोग किए जाने पर यह मानक FolderBrowserDialog पर वापस आ जाता है।
  3. लेखक आपको किसी भी उद्देश्य के लिए कोड का उपयोग करने की अनुमति देता है जो आप फिट हैं।

    कोई लाइसेंस नहीं है जैसे कि आप कोड के साथ लेने के लिए स्वतंत्र हैं और आप क्या करेंगे।

यहां कोड डाउनलोड करें


@MattDavis: मैंने पुष्टि की कि यह .NET फ्रेमवर्क 4.0 (स्टैंडर्ड और क्लाइंट प्रोफाइल दोनों) पर काम करता है। बस सुनिश्चित करें कि आपने अपने प्रोजेक्ट में FolderSelectDialog.cs और Reflector.cs दोनों जोड़े हैं। हालांकि एक बात ... क्या आप विंडोज 8 पर चल रहे हैं? मैंने एक Win7 कंप्यूटर पर परीक्षण किया।
एलेक्स Essilfie

@ एलेक्स एस्सिल्फी, आप सही हैं। मैंने इसे अपनी परियोजना में खींचने में कुछ गलत किया है। मैं स्पष्टता के लिए अपनी पिछली टिप्पणी हटा दूंगा।
मैट डेविस

कई विकल्पों के माध्यम से भागा और यह सबसे अच्छा है। की सिफारिश।
जेंब

मेरे लिए विंडोज़ 10 में काम किया। अच्छा सरल समाधान
डेविड विल्टन

पुराने सिस्टम में फेलओवर का सम्मान करना है
माइक एम

17

सटीक ऑडियो कॉपी इस तरह से विंडोज एक्सपी पर काम करती है। मानक फ़ाइल खुला संवाद दिखाया गया है, लेकिन फ़ाइल फ़ील्ड में "फ़ाइल नाम को अनदेखा किया जाएगा" पाठ शामिल है।

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

संपादित करें: यह मेरे विचार से बहुत आसान है। यहाँ 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: अंत में विजुअल स्टूडियो 2005 में प्रश्न के वास्तविक संवाद को देखा (मुझे पहले इसकी पहुँच नहीं थी)। यह मानक फ़ाइल खुला संवाद नहीं है! यदि आप स्पाई ++ में विंडोज़ का निरीक्षण करते हैं और उनकी तुलना एक मानक फ़ाइल ओपन से करते हैं, तो आप देखेंगे कि संरचना और वर्ग के नाम मेल नहीं खाते। जब आप बारीकी से देखते हैं, तो आप संवादों की सामग्री के बीच कुछ अंतर भी देख सकते हैं। मेरा निष्कर्ष यह है कि Microsoft ने यह क्षमता देने के लिए Visual Studio में मानक संवाद को पूरी तरह से बदल दिया। जब तक आप स्क्रैच से खुद को कोड करने के इच्छुक नहीं होंगे, तब तक मेरा समाधान या कुछ समान आपके पास हो सकता है।


17

ठीक है, मुझे पहली डॉट कनेक्ट करने का प्रयास करें ;-) जासूस ++ या विंस्पेक्टर के साथ थोड़ा सा खेलने से पता चलता है कि वीएस प्रोजेक्ट लोकेशन में फ़ोल्डर टेक्स्टबॉक्स मानक संवाद का एक अनुकूलन है। यह मानक फ़ाइल संवाद में फ़ाइल नाम टेक्स्टबॉक्स के समान फ़ील्ड नहीं है, जैसे कि नोटपैड में।

वहाँ से, मैं आंकड़ा, वी.एस. फ़ाइल नाम और filetype पाठ बॉक्स / comboboxes छुपाता है और संवाद के तल में अपना हिस्सा जोड़ने के लिए एक कस्टम संवाद टेम्पलेट का उपयोग करता है।

संपादित करें: यहां इस तरह के अनुकूलन का एक उदाहरण है और यह कैसे करना है (Win32 में। .NET नहीं):

m_ofn OPENFILENAME संरचना है जो फ़ाइल संवाद को रेखांकित करती है। इन 2 पंक्तियों को जोड़ें:

  m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_FILEDIALOG_IMPORTXLIFF);
  m_ofn.Flags |= OFN_ENABLETEMPLATE;

जहाँ IDD_FILEDIALOG_IMPORTXLIFF एक कस्टम डायलॉग टेम्प्लेट है जिसे डायलॉग के निचले भाग में जोड़ा जाएगा। नीचे का भाग लाल रंग में देखें। (स्रोत: apptranslator.com )वैकल्पिक शब्द

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

लेकिन संवाद के मानक हिस्से में कुछ नियंत्रणों से हमें कैसे छुटकारा मिलेगा, मुझे नहीं पता।

इस MSDN लेख में अधिक विस्तार ।


1
जो कुछ स्पष्टीकरणों की तरह लगता है जो मैंने अतीत में सुना है, लेकिन मैंने कभी भी अवधारणा का प्रदर्शन नहीं देखा है। क्या ऐसा करने के बारे में MSDN प्रलेखन में walkthroughs हैं?
16

10

आप फ़ाइल संवाद को उप-वर्ग कर सकते हैं और इसके सभी नियंत्रणों तक पहुँच प्राप्त कर सकते हैं। प्रत्येक के पास एक पहचानकर्ता होता है जिसका उपयोग उसके विंडो हैंडल को प्राप्त करने के लिए किया जा सकता है। फिर आप उन्हें दिखा सकते हैं और छिपा सकते हैं, चयन परिवर्तन आदि के बारे में उनसे संदेश प्राप्त कर सकते हैं। यह सब निर्भर करता है कि आप कितना प्रयास करना चाहते हैं।

हमने WTL वर्ग समर्थन का उपयोग करते हुए अपना काम किया और कस्टम स्थानों बार और प्लग-इन COM दृश्यों को शामिल करने के लिए फ़ाइल संवाद को अनुकूलित किया।

MSDN Win32 का उपयोग करके इसे कैसे करें के बारे में जानकारी प्रदान करता है, इस CodeProject लेख में एक उदाहरण शामिल है , और यह CodeProject लेख एक .NET उदाहरण प्रदान करता है


10

आप इस तरह कोड का उपयोग कर सकते हैं

  • फ़िल्टर फ़ाइलें छिपा रहा है
  • फ़ाइल नाम पहले पाठ को छिपाता है

फ़ाइल नाम के लिए टेक्स्टबॉक्स के उन्नत छिपाने के लिए आपको OpenFileDialogEx को देखना होगा

कोड:

{
    openFileDialog2.FileName = "\r";
    openFileDialog1.Filter = "folders|*.neverseenthisfile";
    openFileDialog1.CheckFileExists = false;
    openFileDialog1.CheckPathExists = false;
}

सरल है और मुझे विंडोज 7+ के लिए क्या चाहिए
हाओ गुयेन

इसके अलावा झंडे में OFN_NOVALIDATE आवश्यक है
अल्केमिस्ट

5

मुझे लगता है कि आप विस्टा पर VS2008 का उपयोग कर रहे हैं? उस स्थिति में मुझे लगता है कि विस्टा फ़ाइल संवाद IFileDialog को कॉल करते समय FOS_PICKFOLDERS विकल्प का उपयोग किया जा रहा है । मुझे डर है कि .NET कोड में यह काम करने के लिए बहुत सारे P / Invoke इंटरॉप कोड को शामिल करेगा।


1
विस्टा विशेष; मैंने इसे वीएस 2003 पर विंडोज एक्सपी पर पहली बार देखा था।
16

2

पहला उपाय

मैंने बिल विनडाउन डॉटक्वाइन डॉट कॉम (मुझे कोई संबद्धता नहीं है) द्वारा .NET विन 7-स्टाइल फोल्डर सेलेक्ट डायलॉग के क्लीन अप संस्करण के रूप में इसे विकसित किया है। (मैंने इस पृष्ठ पर एक अन्य उत्तर से उनके कोड के बारे में जाना )। मैंने अपना स्वयं का लिखा क्योंकि उनके समाधान के लिए एक अतिरिक्त परावर्तन वर्ग की आवश्यकता है जो इस केंद्रित उद्देश्य के लिए आवश्यक नहीं है, अपवाद-आधारित प्रवाह नियंत्रण का उपयोग करता है, इसके प्रतिबिंब कॉल के परिणामों को कैश नहीं करता है। ध्यान दें कि नेस्टेड स्टैटिक VistaDialogक्लास ऐसा है कि इसका स्टैटिक रिफ्लेक्शन वैरिएबल पॉपुलेटेड होने की कोशिश नहीं करता है अगर Showमेथड कभी नहीं कहा जाता है। यह उच्च-विन्डोज़ संस्करण में नहीं तो पूर्व-विस्टा संवाद पर वापस आता है। विंडोज 7, 8, 9, 10 और उच्चतर (सैद्धांतिक रूप से) में काम करना चाहिए।

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

इसका उपयोग विंडोज फॉर्म में ऐसा किया जाता है:

var dialog = new FolderSelectDialog {
    InitialDirectory = musicFolderTextBox.Text,
    Title = "Select a folder to import music from"
};
if (dialog.Show(Handle)) {
    musicFolderTextBox.Text = dialog.FileName;
}

आप निश्चित रूप से इसके विकल्पों के साथ खेल सकते हैं और यह किन गुणों को उजागर करता है। उदाहरण के लिए, यह विस्टा-शैली संवाद में बहुस्तरीय अनुमति देता है।

दूसरा उपाय

साइमन मूरियर ने एक उत्तर दिया, जो बताता है कि सीधे विंडोज एपीआई के खिलाफ इंटरोप का उपयोग करके सटीक काम कैसे करना है, हालांकि उसके संस्करण को पुराने शैली के संवाद का उपयोग करने के लिए पूरक करना होगा यदि विंडोज के पुराने संस्करण में। दुर्भाग्य से, जब मैंने अपना समाधान किया तब मुझे उनका पद नहीं मिला। अपने जहर का नाम!


इसी तरह के उपयोग उदाहरण इस डायलॉग बॉक्स को खाली हैंडल के साथ डायलॉग बॉक्स (जैसे कंसोल-टाइप ऐप्स) के रूप में कॉल करने के लिए: सही बॉक्स को संकलित करता है: var डायलॉग = नया FolderSelectDialog {InitialDirectory = "C: \\", Title = "a चुनें "} से संगीत आयात करने के लिए फ़ोल्डर; if (डायलॉग .how ()) {string myFolder = dialog.FileName; }
फिलम

नोट: एक टिप्पणी के रूप में मेरा उपयोग उदाहरण पढ़ना मुश्किल है, इसलिए: मूल उपयोग के लिए सबसे महत्वपूर्ण बदलाव "उदाहरण":
प्रारंभिकडायरेक्टरी

1

से यह एक प्रयास करें codeproject (नाइट्रन को ऋण):

मुझे लगता है कि यह वही डायलॉग है जिसके बारे में आप बात कर रहे हैं - यदि आप स्क्रीनशॉट जोड़ते हैं तो शायद यह मदद करेगा?

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

images.google.com/ ... अनिश्चित होने पर शोध करें। मैंने वर्णन किया कि मुझे क्या चाहिए था, और FolderBrowserDialog को पहले ही उत्तर के रूप में अयोग्य घोषित कर दिया गया है।
16

"मैं FolderBrowserDialog से वाकिफ हूं, लेकिन मुझे वास्तव में वह डायलॉग कभी पसंद नहीं आया। यह बहुत छोटा है और मुझे एक रास्ता टाइप करने में सक्षम होने का फायदा नहीं उठाने देता।" अपने आप से कुछ शोध करें - आप वहां एक मार्ग टाइप कर सकते हैं। वैसे भी मुझे लगता है कि यह थोड़ा अस्पष्ट सवाल है, इसलिए इसके साथ शुभकामनाएं।
demoncodemonkey

@demoncodemonkey: आप पथ के एक भाग में टाइप नहीं कर सकते हैं और फिर इच्छित लक्ष्य पर नेविगेट कर सकते हैं। जहाँ तक विकल्प के रूप में सुविधाजनक नहीं है, FileOpenDialog प्रस्ताव।
ट्रेब

1

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

पुराने विंडोज के लिए आप हमेशा फोल्डर में किसी भी फाइल को चुनने के लिए ट्रिक का सहारा ले सकते हैं।

वर्किंग उदाहरण जो .NET फ्रेमवर्क 2.0 पर काम करता है और बाद में यहां पाया जा सकता है


1

आप इस तरह कोड का उपयोग कर सकते हैं

फिल्टर खाली स्ट्रिंग है। फ़ाइल नाम AnyName है, लेकिन रिक्त नहीं है

        openFileDialog.FileName = "AnyFile";
        openFileDialog.Filter = string.Empty;
        openFileDialog.CheckFileExists = false;
        openFileDialog.CheckPathExists = false;

6
मुझे पता है कि यह एक पुरानी पोस्ट है, लेकिन जो कोई भी इसे आज़माना चाहता है, उसके लिए यह वास्तव में तब तक काम नहीं करता है जब तक कि जिस निर्देशिका को आप खोलना चाहते हैं, उसकी बिल्कुल भी कोई बाल निर्देशिका नहीं है। इसलिए यदि मैं अपने उपयोगकर्ता को किसी फ़ोल्डर में ब्राउज़ करने देना चाहता हूं और उसका चयन करना चाहता हूं, और कुछ टेक्स्ट बॉक्स में फ़ोल्डर पथ को पॉप्युलेट करता हूं, तो उपयोगकर्ता कभी भी C: \ SomeParentDir का चयन नहीं कर सकता है यदि निर्देशिका C: \ SomeParentDir \ SomeCildDir मौजूद है, क्योंकि "ओपन" का चयन करना "बस आपको बाल निर्देशिका में लाता है।
जिम

अच्छी कोशिश .. लेकिन इसका नतीजा यह है कि टेक्स्टबॉक्स में "AnyFile" के रूप में भयानक UI में उपयोगकर्ता को अपने पाठ को ओवरराइड करने की प्रतीक्षा है .. इसके अलावा उपयोगकर्ता फ़ाइलों का चयन भी कर सकता है - बहुत अच्छा नहीं। लेकिन अच्छी कोशिश ..
GY

1

WPF के लिए Ookii संवाद पुस्तकालय एक वर्ग है कि WPF के लिए एक फ़ोल्डर ब्राउज़र संवाद के एक कार्यान्वयन प्रदान करता है।

https://github.com/augustoproiete/ookii-dialogs-wpf

यहां छवि विवरण दर्ज करें

एक संस्करण भी है जो विंडोज फॉर्म के साथ काम करता है ।


-1

मुझे पता है कि प्रश्न कॉन्फ़िगरेशन पर था, OpenFileDialogलेकिन यह देखते हुए कि Google ने मुझे यहां लाया था, साथ ही मैं यह भी बता सकता हूं कि यदि आप केवल उन फ़ोल्डरों की तलाश कर रहे हैं जिन्हें आपको उपयोग करना चाहिएFolderBrowserDialog अन्य SO प्रश्न के उत्तर के अनुसार

Vb.net में खुले फ़ाइल संवाद का उपयोग करके पथ कैसे निर्दिष्ट करें?


गुमराह करने वाले। 1) यह नहीं एकमात्र विकल्प; 2) यह ज्यादातर मामलों में अच्छा विकल्प नहीं है; फिर भी इसे कम से कम कोड की आवश्यकता होती है, जो अधिक अंत-उपयोगकर्ता द्वारा बिताए गए समय के अनुसार होता है।
मेव कैट 2012
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.