programing

WPF에는 네이티브 파일 대화 상자가 있습니까?

lovejava 2023. 5. 29. 09:03

WPF에는 네이티브 파일 대화 상자가 있습니까?

아래System.Windows.Controls나는 볼 수 있습니다.PrintDialog하지만, 나는 네이티브를 찾을 수 없는 것 같습니다.FileDialog다음에 대한 참조를 만들어야 합니까?System.Windows.Forms아니면 다른 방법이 있습니까?

WPF에는 기본 제공 파일 대화 상자가 있습니다.구체적으로, 그들은 약간 예상치 못한 상황에 있습니다.Microsoft.Win32네임스페이스(아직 WPF의 일부이지만).특히 및 클래스를 참조하십시오.

그러나 이러한 클래스는 상위 네임스페이스에서 알 수 있듯이 Win32 기능에 대한 래퍼일 뿐입니다.그러나 WinForms 또는 Win32 interop을 수행할 필요가 없으므로 사용하기가 다소 좋습니다.유감스럽게도 대화상자는 기본적으로 "이전" Windows 테마의 스타일이며, 당신은 작은 해킹이 필요합니다.app.manifest새 것을 사용하도록 강제하는 것.

단순 연결 속성을 만들어 텍스트 상자에 이 기능을 추가할 수 있습니다.파일 열기 대화 상자는 다음과 같이 사용할 수 있습니다.

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

        };
      };
    }
}

Gregor 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

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

언급URL : https://stackoverflow.com/questions/1482486/does-wpf-have-a-native-file-dialog