2009-09-27 6 views
45

Unter System.Windows.Controls kann ich eine PrintDialog sehen, aber ich kann nicht scheinen, eine native FileDialog zu finden. Muss ich einen Verweis auf System.Windows.Forms erstellen oder gibt es einen anderen Weg?Hat WPF einen nativen Dateidialog?

Antwort

60

WPF hat eingebaute (obwohl nicht native) Dateidialoge. Insbesondere befinden sie sich im leicht unerwarteten -Namespace (obwohl sie immer noch Teil von WPF sind). Siehe insbesondere die Klassen OpenFileDialog und SaveFileDialog.

Beachten Sie jedoch, dass diese Klassen nur Wrapper um die Win32-Funktionalität sind, wie der übergeordnete Namespace vermuten lässt. Es bedeutet jedoch, dass Sie kein WinForms- oder Win32-Interop machen müssen, was die Verwendung etwas angenehmer macht. Leider sind die Dialoge standardmäßig im "alten" Windows-Design und Sie benötigen einen kleinen Hack in app.manifest, um es zu zwingen, den neuen zu verwenden.

+3

Würde es Ihnen etwas ausmachen, zu überlegen, was mit dem Manifest getan werden muss, um die neue Windows-Designversion zu erhalten? –

+2

@Sebastian: Sicher - es ist in diesem Blog-Beitrag detailliert: http://www.nbdtech.com/blog/archive/2008/06/16/The-Application-Manifest-Neded-for-XP-and-Vista-Style -File.aspx. – Noldorin

15

Sie können eine einfache angefügte Eigenschaft erstellen, um diese Funktionalität zu einer TextBox hinzuzufügen. Datei öffnen Dialog können wie diese verwendet werden:

<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="*"/> 
     <ColumnDefinition Width="Auto"/> 
    </Grid.ColumnDefinitions> 
    <TextBox i:OpenFileDialogEx.Filter="Excel documents (.xls)|*.xls" Grid.Column="0" /> 
    <Button Grid.Column="1">Browse</Button> 
</Grid> 

Der Code für OpenFileDialogEx:

public class OpenFileDialogEx 
{ 
    public static readonly DependencyProperty FilterProperty = 
     DependencyProperty.RegisterAttached("Filter", 
     typeof (string), 
     typeof (OpenFileDialogEx), 
     new PropertyMetadata("All documents (.*)|*.*", (d, e) => AttachFileDialog((TextBox) d, e))); 

    public static string GetFilter(UIElement element) 
    { 
     return (string)element.GetValue(FilterProperty); 
    } 

    public static void SetFilter(UIElement element, string value) 
    { 
     element.SetValue(FilterProperty, value); 
    } 

    private static void AttachFileDialog(TextBox textBox, DependencyPropertyChangedEventArgs args) 
    {     
     var parent = (Panel) textBox.Parent; 

     parent.Loaded += delegate { 

     var button = (Button) parent.Children.Cast<object>().FirstOrDefault(x => x is Button); 

     var filter = (string) args.NewValue; 

     button.Click += (s, e) => { 
      var dlg = new OpenFileDialog(); 
      dlg.Filter = filter; 

      var result = dlg.ShowDialog(); 

      if (result == true) 
      { 
      textBox.Text = dlg.FileName; 
      } 

     }; 
     }; 
    } 
} 
3

ich die Lösung von Gregor S. vorgestellt verwendet, und es funktioniert gut, obwohl ich hatte Konvertieren Sie es in eine VB.NET-Lösung, hier ist meine Umwandlung, wenn es jemand hilft ...

2

Dank Gregor S für eine saubere Lösung.

In Visual Studio 2010 scheint es den Designer jedoch zum Absturz zu bringen - also habe ich den Code in der OpenFileDialogEx-Klasse optimiert. Der XAML-Code bleibt gleich:

public class OpenFileDialogEx 
{ 
    public static readonly DependencyProperty FilterProperty = 
     DependencyProperty.RegisterAttached(
      "Filter", 
      typeof(string), 
      typeof(OpenFileDialogEx), 
      new PropertyMetadata("All documents (.*)|*.*", (d, e) => AttachFileDialog((TextBox)d, e)) 
     ); 


    public static string GetFilter(UIElement element) 
    { 
     return (string)element.GetValue(FilterProperty); 
    } 

    public static void SetFilter(UIElement element, string value) 
    { 
     element.SetValue(FilterProperty, value); 
    } 

    private static void AttachFileDialog(TextBox textBox, DependencyPropertyChangedEventArgs args) 
    { 
     var textBoxParent = textBox.Parent as Panel; 
     if (textBoxParent == null) 
     { 
      Debug.Print("Failed to attach File Dialog Launching Button Click Handler to Textbox parent panel!"); 
      return; 
     } 


     textBoxParent.Loaded += delegate 
     { 
      var button = textBoxParent.Children.Cast<object>().FirstOrDefault(x => x is Button) as Button; 
      if (button == null) 
       return; 

      var filter = (string)args.NewValue; 

      button.Click += (s, e) => 
      { 
       var dlg = new OpenFileDialog { Filter = filter }; 

       var result = dlg.ShowDialog(); 

       if (result == true) 
       { 
        textBox.Text = dlg.FileName; 
       } 
      }; 
     }; 
    } 
}