48 votes

Ne WPF avoir un fichier natif de dialogue?

En vertu de l' System.Windows.Controls, je peux voir un PrintDialog Cependant, je n'arrive pas à trouver un natif FileDialog. Dois-je créer une référence à l' System.Windows.Forms ou est-il un autre moyen?

62voto

Noldorin Points 67794

WPF n'avez intégré (bien que n'étant pas natif) boîtes de dialogue fichier. Plus précisément, ils sont un peu inattendu Microsoft.Win32 d'espace de noms (bien que toujours partie de WPF). Voir l' OpenFileDialog et SaveFileDialog des classes en particulier.

Toutefois, de noter que ces classes ne sont que des wrappers autour du Win32 fonctionnalités, comme l'espace de noms parent suggère. Cela signifie néanmoins que vous n'avez pas besoin de faire un WinForms ou Win32 l'interopérabilité, ce qui le rend un peu plus agréable à utiliser. Malheureusement, les dialogues sont, par défaut, le style de la "vieille" Windows thème, et vous avez besoin d'un petit hack dans app.manifest pour le forcer à utiliser le nouveau.

15voto

Gregor S. Points 1867

Vous pouvez créer une simple propriété attachée à ajouter cette fonctionnalité à une zone de texte. Dialogue d'ouverture de fichier peuvent être utilisés comme ceci:

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

Le code pour 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;
          }

        };
      };
    }
}

3voto

Jbtatro Points 21

J'ai utilisé la solution présentée par Gregor S. et il fonctionne bien, même si j'ai eu à le convertir en un VB.NET la solution, voici ma conversion si ça aide quelqu'un...

Imports System
Imports Microsoft.Win32

Public Class OpenFileDialogEx
    Public Shared ReadOnly FilterProperty As DependencyProperty = DependencyProperty.RegisterAttached("Filter", GetType(String), GetType(OpenFileDialogEx), New PropertyMetadata("All documents (.*)|*.*", Sub(d, e) AttachFileDialog(DirectCast(d, TextBox), e)))
    Public Shared Function GetFilter(element As UIElement) As String
        Return DirectCast(element.GetValue(FilterProperty), String)
    End Function

    Public Shared Sub SetFilter(element As UIElement, value As String)
        element.SetValue(FilterProperty, value)
    End Sub


    Private Shared Sub AttachFileDialog(textBox As TextBox, args As DependencyPropertyChangedEventArgs)
        Dim parent = DirectCast(textBox.Parent, Panel)
        AddHandler parent.Loaded, Sub()

          Dim button = DirectCast(parent.Children.Cast(Of Object)().FirstOrDefault(Function(x) TypeOf x Is Button), Button)
          Dim filter = DirectCast(args.NewValue, String)
            AddHandler button.Click, Sub(s, e)
               Dim dlg = New OpenFileDialog()
               dlg.Filter = filter
               Dim result = dlg.ShowDialog()
               If result = True Then
                   textBox.Text = dlg.FileName
               End If
            End Sub
        End Sub
    End Sub
End Class

2voto

Daniel Scott Points 23

Grâce à Gregor S pour une solution élégante.

Dans Visual Studio 2010, il semble planter le designer toutefois - j'ai donc modifié le code dans le OpenFileDialogEx classe. Le code XAML reste le même:

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X