diff --git a/demo/Semi.Avalonia.Demo/Pages/ManagedFileChooserDemo.axaml b/demo/Semi.Avalonia.Demo/Pages/ManagedFileChooserDemo.axaml
new file mode 100644
index 0000000..b583dc5
--- /dev/null
+++ b/demo/Semi.Avalonia.Demo/Pages/ManagedFileChooserDemo.axaml
@@ -0,0 +1,16 @@
+
+
+
+
+
+
+
diff --git a/demo/Semi.Avalonia.Demo/Pages/ManagedFileChooserDemo.axaml.cs b/demo/Semi.Avalonia.Demo/Pages/ManagedFileChooserDemo.axaml.cs
new file mode 100644
index 0000000..9d40153
--- /dev/null
+++ b/demo/Semi.Avalonia.Demo/Pages/ManagedFileChooserDemo.axaml.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Dialogs;
+using Avalonia.Interactivity;
+using Avalonia.Markup.Xaml;
+using Avalonia.Platform.Storage;
+
+namespace Semi.Avalonia.Demo.Pages;
+
+public partial class ManagedFileChooserDemo : UserControl
+{
+ public ManagedFileChooserDemo()
+ {
+ InitializeComponent();
+ openFileDialog.Click += OpenFileDialog;
+ selectFolderDialog.Click += SelectFolderDialog;
+ saveFileDialog.Click += SaveFileDialog;
+ }
+
+ private async void OpenFileDialog(object sender, RoutedEventArgs args)
+ {
+ IStorageProvider sp = GetStorageProvider();
+ var result = await sp.OpenFilePickerAsync(new FilePickerOpenOptions()
+ {
+ Title = "Open File",
+ FileTypeFilter = GetFileTypes(),
+ AllowMultiple = true,
+ });
+ }
+ private async void SelectFolderDialog(object sender, RoutedEventArgs args)
+ {
+ IStorageProvider sp = GetStorageProvider();
+ var result = await sp.OpenFolderPickerAsync(new FolderPickerOpenOptions()
+ {
+ Title = "Select Folder",
+ AllowMultiple = true,
+ });
+ }
+ private async void SaveFileDialog(object sender, RoutedEventArgs args)
+ {
+ IStorageProvider sp = GetStorageProvider();
+ var result = await sp.SaveFilePickerAsync(new FilePickerSaveOptions()
+ {
+ Title = "Open File",
+ });
+ }
+
+ private IStorageProvider GetStorageProvider()
+ {
+ return new ManagedStorageProvider(GetWindow(), null);
+ }
+
+ private static string FullPathOrName(IStorageItem? item)
+ {
+ if (item is null) return "(null)";
+ return item.TryGetUri(out var uri) ? uri.ToString() : item.Name;
+ }
+
+ Window GetWindow() => this.VisualRoot as Window ?? throw new NullReferenceException("Invalid Owner");
+ TopLevel GetTopLevel() => this.VisualRoot as TopLevel ?? throw new NullReferenceException("Invalid Owner");
+
+ List? GetFileTypes()
+ {
+ return new List
+ {
+ FilePickerFileTypes.All,
+ FilePickerFileTypes.TextPlain
+ };
+ }
+}
\ No newline at end of file
diff --git a/demo/Semi.Avalonia.Demo/Views/MainView.axaml b/demo/Semi.Avalonia.Demo/Views/MainView.axaml
index 8e2ffe4..8a1abd7 100644
--- a/demo/Semi.Avalonia.Demo/Views/MainView.axaml
+++ b/demo/Semi.Avalonia.Demo/Views/MainView.axaml
@@ -60,6 +60,9 @@
+
+
+
diff --git a/src/Semi.Avalonia/Controls/Controls.axaml b/src/Semi.Avalonia/Controls/Controls.axaml
index 866cc49..8b4b895 100644
--- a/src/Semi.Avalonia/Controls/Controls.axaml
+++ b/src/Semi.Avalonia/Controls/Controls.axaml
@@ -22,6 +22,7 @@
+
diff --git a/src/Semi.Avalonia/Controls/ManagedFileChooser.axaml b/src/Semi.Avalonia/Controls/ManagedFileChooser.axaml
new file mode 100644
index 0000000..0c583bd
--- /dev/null
+++ b/src/Semi.Avalonia/Controls/ManagedFileChooser.axaml
@@ -0,0 +1,176 @@
+
+
+
+
+
+
+
+
+
+ M19,20H4C2.89,20 2,19.1 2,18V6C2,4.89 2.89,4 4,4H10L12,6H19A2,2 0 0,1 21,8H21L4,8V18L6.14,10H23.21L20.93,18.5C20.7,19.37 19.92,20 19,20Z
+ M13,9H18.5L13,3.5V9M6,2H14L20,8V20A2,2 0 0,1 18,22H6C4.89,22 4,21.1 4,20V4C4,2.89 4.89,2 6,2M15,18V16H6V18H15M18,14V12H6V14H18Z
+ M6,2H18A2,2 0 0,1 20,4V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V4A2,2 0 0,1 6,2M12,4A6,6 0 0,0 6,10C6,13.31 8.69,16 12.1,16L11.22,13.77C10.95,13.29 11.11,12.68 11.59,12.4L12.45,11.9C12.93,11.63 13.54,11.79 13.82,12.27L15.74,14.69C17.12,13.59 18,11.9 18,10A6,6 0 0,0 12,4M12,9A1,1 0 0,1 13,10A1,1 0 0,1 12,11A1,1 0 0,1 11,10A1,1 0 0,1 12,9M7,18A1,1 0 0,0 6,19A1,1 0 0,0 7,20A1,1 0 0,0 8,19A1,1 0 0,0 7,18M12.09,13.27L14.58,19.58L17.17,18.08L12.95,12.77L12.09,13.27Z
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Semi.Avalonia/Themes/Light/Light.axaml b/src/Semi.Avalonia/Themes/Light/Light.axaml
index 516e71e..f0e2aa7 100644
--- a/src/Semi.Avalonia/Themes/Light/Light.axaml
+++ b/src/Semi.Avalonia/Themes/Light/Light.axaml
@@ -18,6 +18,7 @@
+
diff --git a/src/Semi.Avalonia/Themes/Light/ManagedFileChooser.axaml b/src/Semi.Avalonia/Themes/Light/ManagedFileChooser.axaml
new file mode 100644
index 0000000..ed63ac9
--- /dev/null
+++ b/src/Semi.Avalonia/Themes/Light/ManagedFileChooser.axaml
@@ -0,0 +1,7 @@
+
+
+
+
+
+ M20 18V20H13.5C9.91 20 7 17.09 7 13.5V7.83L3.91 10.92L2.5 9.5L8 4L13.5 9.5L12.09 10.91L9 7.83V13.5C9 16 11 18 13.5 18H20Z
+