WPF是否有一个本地文件对话框?(Does WPF have a native file dialo

2019-08-16 22:22发布

System.Windows.Controls ,我可以看到一个PrintDialog不过,我似乎无法找到一个本地FileDialog 。 我需要创建一个参考System.Windows.Forms或有另一种方式?

Answer 1:

WPF确实有内置的(虽然不是本机 )文件对话框。 具体而言,它们在略微意想不到Microsoft.Win32命名空间(WPF的虽然仍然一部分)。 见OpenFileDialogSaveFileDialog特别班。

不过,别注意,这些类是围绕Win32的功能只是包装,作为父命名空间建议。 然而,这确实意味着你不需要做任何的WinForms或Win32的互操作,这使得它有点更好用。 不幸的是,对话是默认的风格,在“旧” Windows主题,你需要在一个小黑客app.manifest ,迫使它使用新的一个。



Answer 2:

你可以创建一个简单的附加属性这个功能添加到一个文本框。 打开文件对话框,可以使用如下

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

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

        };
      };
    }
}


Answer 3:

我使用的格雷戈尔S.提出的解决方案,它工作得很好,但我不得不将其转换为VB.NET的解决方案,这是我的转换,如果它可以帮助任何人...

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


Answer 4:

由于格雷戈尔S代表一个整洁的解决方案。

在Visual Studio 2010中似乎然而崩溃设计师 - 所以我调整了在OpenFileDialogEx类的代码。 该XAML代码保持不变:

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


文章来源: Does WPF have a native file dialog?