System.Windows.Controls
の下にPrintDialog
が表示されますが、ネイティブFileDialog
が見つからないようです。 System.Windows.Forms
への参照を作成する必要がありますか、それとも別の方法がありますか?
WPFには(nativeではない)ファイルダイアログが組み込まれています。具体的には、わずかに予期しないMicrosoft.Win32
名前空間(まだWPFの一部ですが)。特に OpenFileDialog
および SaveFileDialog
クラスを参照してください。
ただし、これらのクラスは、Win32機能のラッパーにすぎないことに注意してください。これは、親の名前空間が示唆しているとおりです。ただし、WinFormsやWin32の相互運用を行う必要がないことを意味しているため、使用するのが多少便利です。残念ながら、ダイアログはデフォルトで「古い」Windowsテーマのスタイルであり、app.manifest
新しいものを使用するように強制します。
単純な添付プロパティを作成して、この機能をTextBoxに追加できます。 ファイルを開くダイアログは次のように使用できます:
<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;
}
};
};
}
}