2010-10-24 13 views
55

मैं एक WPF4 एप्लिकेशन विकसित करता हूं और मेरे ऐप में मुझे उपयोगकर्ता को ऐसे फ़ोल्डर का चयन करने की आवश्यकता होती है जहां एप्लिकेशन कुछ स्टोर करेगा (फाइलें, जेनरेट की गई रिपोर्ट इत्यादि)।फ़ोल्डर संवाद का चयन करें WPF

मेरे आवश्यकताओं:

  • मानक फ़ोल्डर ट्री को देखने के लिए

  • WPF देखने & महसूस एक फ़ोल्डर का चयन करने के लिए

  • की क्षमता की क्षमता है, इस संवाद एक आधुनिक का हिस्सा की तरह लग रहे चाहिए विंडोज विस्टा/7 के लिए डिज़ाइन किया गया एप्लिकेशन और विंडोज 2000 या Win9x भी नहीं।

के रूप में मैं समझता हूँ, जब तक 2010 (नेट 4.0) एक मानक फ़ोल्डर संवाद नहीं होगा, लेकिन शायद वहाँ संस्करण 4.0 में कुछ बदलाव कर रहे हैं?

या बाकी सब कुछ करने के लिए पुराना स्कूल WinForms संवाद का उपयोग करना है? अगर मुझे ऐसा करने का एकमात्र तरीका है, तो मैं इसे Vista/7 शैली के करीब कैसे बना सकता हूं और Win9x नहीं?

कुछ मंचों पर, मैंने इस तरह के संवादों के कार्यान्वयन को देखा, लेकिन पुराने बदसूरत आइकन à la विंडोज 95 के साथ। यह वास्तव में अच्छा नहीं लग रहा है।

+2

चेक बाहर स्वेन Groot की शानदार [Ookii.Dialogs] (करने के लिए http The Windows API Code Pack-Shell जोड़ें: // www.ookii.org/software/dialogs/) WinForms और WPF दोनों के लिए, जो आपको आधुनिक "Vista" शैली फ़ोल्डर और फ़ाइल संवाद देता है। –

+0

मैं wxPython पायथन मॉड्यूल का उपयोग कर रहा हूं https://github.com/wxWidgets/Phoenix – JinSnow

उत्तर

18

मैंने अपने ब्लॉग पर बहुत समय पहले लिखा था, आम फ़ाइल संवाद के लिए डब्ल्यूपीएफ का समर्थन वास्तव में खराब है (या कम से कम 3.5 में था, मैंने संस्करण 4 में जांच नहीं की थी) - लेकिन इसके आसपास काम करना आसान है ।

आपको अपने एप्लिकेशन में सही मैनिफेस्ट जोड़ने की ज़रूरत है - जो आपको एक आधुनिक स्टाइल संदेश बॉक्स और फ़ोल्डर ब्राउज़र (WinForms FolderBrowserDialog) देगा, लेकिन WPF फ़ाइल खुला/सहेजने वाले संवाद नहीं, यह उन 3 पदों में वर्णित है (यदि आप स्पष्टीकरण के बारे में परवाह नहीं है और एकमात्र समाधान 3 पर सीधे जाने चाहते हैं):

सौभाग्य से, खुला/बचाने के संवाद Win32 एपीआई (प्रकट करने के बाद) Vista/7 शैली पाने के लिए

सही झंडे के साथ कॉल करने के लिए आसान है कि चारों ओर बहुत पतली रैपर हैं
5

माइक्रोसॉफ्ट.Win32.OpenFileDialog मानक संवाद है कि विंडोज पर कोई भी एप्लीकेशन उपयोग करता है। जब आप .NET 4.0

में WPF का उपयोग करते हैं तो आपका उपयोगकर्ता इसकी उपस्थिति से आश्चर्यचकित नहीं होगा। .NET 3.0 और 3.5 में डब्ल्यूपीएफ ने अभी भी विरासत संवाद का उपयोग किया लेकिन यह .NET 4.0 में तय किया गया था। मैं केवल अनुमान लगा सकता हूं कि आपने यह धागा शुरू किया क्योंकि आप उस पुराने संवाद को देख रहे हैं। जिसका अर्थ है कि आप वास्तव में एक प्रोग्राम चला रहे हैं जो 3.5 को लक्षित कर रहा है। हां, Winforms wrapper अपग्रेड प्राप्त करें और Vista संस्करण दिखाता है। System.Windows.Forms.OpenFileDialog क्लास, आपको System.Windows.Forms का संदर्भ जोड़ना होगा।

+13

मुझे लगता है कि बिंदु यह है कि किसी फ़ोल्डर का चयन करने के लिए OpenFileDialog का उपयोग नहीं किया जा सकता है। – Neutrino

0

केवल ऐसा संवाद FileDialog है। WinForms का इसका हिस्सा है, लेकिन यह वास्तव में WinAPI मानक ओएस फ़ाइल संवाद के आसपास केवल रैपर है। और मुझे नहीं लगता कि यह बदसूरत है, यह वास्तव में ओएस का हिस्सा है, इसलिए ऐसा लगता है कि ओएस चालू है।

अन्य तरीकों से, आपकी सहायता करने के लिए कुछ भी नहीं है। आपको या तो तीसरे पक्ष के कार्यान्वयन की तलाश करनी होगी, या तो मुफ्त (और मुझे नहीं लगता कि कोई अच्छा है) या भुगतान किया गया है।

+0

धन्यवाद! यह अब तक का सबसे अच्छा जवाब है। एमवीवीएम या मानक विंडोज़ के लिए कोड के लिए बहुत आसान है। –

+2

लेकिन यह आपको एक फ़ोल्डर चुनने की अनुमति नहीं देता है ... –

86

Windows Presentation Foundation 4.5 Cookbook पावेल Yosifovich द्वारा "आम संवाद बॉक्स का उपयोग करना" पर अनुभाग में पृष्ठ 155 पर कहते हैं:

"क्या फ़ोल्डर चयन (फ़ाइलों के बजाय) के बारे में? WPF OpenFileDialog इसका समर्थन नहीं करता है। एक समाधान विंडोज फॉर्म 'फ़ोल्डर्स ब्रोसेडियलॉग क्लास का उपयोग करना है। एक और अच्छा समाधान Windows API कोड पैक शीघ्र ही वर्णित उपयोग करने के लिए है। "

मैं Windows® API Code Pack for Microsoft® .NET FrameworkWindows API Code Pack: Where is it? से एपीआई कोड पैक डाउनलोड किया है, तो Microsoft.WindowsAPICodePack.dll और Microsoft.WindowsAPICodePack.Shell के लिए संदर्भ गयी। मेरी WPF 4.5 परियोजना के लिए dll

उदाहरण:।

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 
} 
+92

प्रश्न का पूरा बिंदु मुझे विश्वास नहीं है कि माइक्रोसॉफ्ट ने WPF में डिफ़ॉल्ट रूप से फ़ोल्डर ब्रोसर डायलॉग को शामिल करने के लिए परेशान नहीं किया है ... – Snooze

+18

विंडोज एपीआई कोड पैक Nuget के माध्यम से उपलब्ध हैं [यहां] (http://www.nuget.org/packages/Windows7APICodePack-Shell/) और [यहां] (https://www.nuget.org/packages/Windows7APICodePack-Core/)। यह मेरे लिए अच्छा काम किया। – Wally

+2

यह मेरे साथ ठीक काम करता है। इसके अलावा मैं बस नीचे दिए गए आदेश लिखता हूं ताकि पोस्ट में सभी जानकारी हो। पैकेज प्रबंधक कंसोल के माध्यम से स्थापित वी.एस. में "स्थापित-पैकेज Windows7APICodePack कोर" , "स्थापित-पैकेज Windows7APICodePack-शैल" –

5

MVVM + WinForms FolderBrowserDialog व्यवहार के रूप में

public class FolderDialogBehavior : Behavior<Button> 
{ 
    public string SetterName { get; set; } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.Click += OnClick; 
    } 

    protected override void OnDetaching() 
    { 
     AssociatedObject.Click -= OnClick; 
    } 

    private void OnClick(object sender, RoutedEventArgs e) 
    { 
     var dialog = new FolderBrowserDialog(); 
     var result = dialog.ShowDialog(); 
     if (result == DialogResult.OK && AssociatedObject.DataContext != null) 
     { 
      var propertyInfo = AssociatedObject.DataContext.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public) 
      .Where(p => p.CanRead && p.CanWrite) 
      .Where(p => p.Name.Equals(SetterName)) 
      .First(); 

      propertyInfo.SetValue(AssociatedObject.DataContext, dialog.SelectedPath, null); 
     } 
    } 
} 

प्रयोग

 <Button Grid.Column="3" Content="..."> 
      <Interactivity:Interaction.Behaviors> 
       <Behavior:FolderDialogBehavior SetterName="SomeFolderPathPropertyName"/> 
      </Interactivity:Interaction.Behaviors> 
    </Button> 

ब्लॉगपोस्ट: http://kostylizm.blogspot.ru/2014/03/wpf-mvvm-and-winforms-folder-dialog-how.html

1

खेल के जवाब के आधार पर यह फ़ोल्डर के लिए एक निर्भरता संपत्ति का उपयोग करना बेहतर है। यह उप-गुणों के लिए बाध्यकारी (उदाहरण के लिए) की अनुमति देता है, जो मूल में काम नहीं करता है। साथ ही, मेरे समायोजित संस्करण में, संवाद शो प्रारंभिक फ़ोल्डर का चयन करता है। XAML में

उपयोग:

<Button Content="..."> 
    <i:Interaction.Behaviors> 
     <Behavior:FolderDialogBehavior FolderName="{Binding FolderPathPropertyName, Mode=TwoWay}"/> 
    </i:Interaction.Behaviors> 
</Button> 

कोड:

using System.Windows; 
using System.Windows.Forms; 
using System.Windows.Interactivity; 
using Button = System.Windows.Controls.Button; 

public class FolderDialogBehavior : Behavior<Button> 
{ 
    #region Attached Behavior wiring 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.Click += OnClick; 
    } 

    protected override void OnDetaching() 
    { 
     AssociatedObject.Click -= OnClick; 
     base.OnDetaching(); 
    } 
    #endregion 

    #region FolderName Dependency Property 
    public static readonly DependencyProperty FolderName = 
      DependencyProperty.RegisterAttached("FolderName", 
      typeof(string), typeof(FolderDialogBehavior)); 

    public static string GetFolderName(DependencyObject obj) 
    { 
     return (string)obj.GetValue(FolderName); 
    } 

    public static void SetFolderName(DependencyObject obj, string value) 
    { 
     obj.SetValue(FolderName, value); 
    } 
    #endregion 

    private void OnClick(object sender, RoutedEventArgs e) 
    { 
     var dialog = new FolderBrowserDialog(); 
     var currentPath = GetValue(FolderName) as string; 
     dialog.SelectedPath = currentPath; 
     var result = dialog.ShowDialog(); 
     if (result == DialogResult.OK) 
     { 
      SetValue(FolderName, dialog.SelectedPath); 
     } 
    } 
} 
+0

इसे साथ संयोजित करें @ टीपीओर्स जवाब देते हैं और यह बहुत अच्छा काम करता है। इसके अलावा, "i" नामस्थान के लिए .. 'xmlns: i =" http://schemas.microsoft.com/expression/2010/interactivity "' – bdeem

5

अपनी परियोजना

using Microsoft.WindowsAPICodePack.Dialogs; 

... 

var dialog = new CommonOpenFileDialog(); 
dialog.IsFolderPicker = true; 
CommonFileDialogResult result = dialog.ShowDialog(); 
संबंधित मुद्दे