Browse Source

spaces not tabs!

pull/2777/head
Dan Walmsley 7 years ago
parent
commit
79b3085096
  1. 9
      samples/ControlCatalog.NetCore/Program.cs
  2. 40
      src/Avalonia.Dialogs/ByteSizeHelper.cs
  3. 24
      src/Avalonia.Dialogs/ChildFitter.cs
  4. 28
      src/Avalonia.Dialogs/FileSizeStringConverter.cs
  5. 4
      src/Avalonia.Dialogs/ManagedFileChooser.xaml
  6. 148
      src/Avalonia.Dialogs/ManagedFileChooser.xaml.cs
  7. 84
      src/Avalonia.Dialogs/ManagedFileChooserFilterViewModel.cs
  8. 108
      src/Avalonia.Dialogs/ManagedFileChooserItemViewModel.cs
  9. 8
      src/Avalonia.Dialogs/ManagedFileChooserNavigationItem.cs
  10. 142
      src/Avalonia.Dialogs/ManagedFileChooserSources.cs
  11. 614
      src/Avalonia.Dialogs/ManagedFileChooserViewModel.cs
  12. 16
      src/Avalonia.Dialogs/ManagedFileDialogExtensions.cs
  13. 22
      src/Avalonia.Dialogs/ResourceSelectorConverter.cs

9
samples/ControlCatalog.NetCore/Program.cs

@ -31,7 +31,7 @@ namespace ControlCatalog.NetCore
}
var builder = BuildAvaloniaApp();
if (args.Contains("--fbdev"))
{
SilenceConsole();
@ -45,14 +45,14 @@ namespace ControlCatalog.NetCore
else
return builder.StartWithClassicDesktopLifetime(args);
}
/// <summary>
/// This method is needed for IDE previewer infrastructure
/// </summary>
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>()
.UsePlatformDetect()
.With(new X11PlatformOptions {EnableMultiTouch = true})
.With(new X11PlatformOptions { EnableMultiTouch = true })
.With(new Win32PlatformOptions
{
EnableMultitouch = true,
@ -69,7 +69,8 @@ namespace ControlCatalog.NetCore
Console.CursorVisible = false;
while (true)
Console.ReadKey(true);
}) {IsBackground = true}.Start();
})
{ IsBackground = true }.Start();
}
}
}

40
src/Avalonia.Dialogs/ByteSizeHelper.cs

@ -1,25 +1,25 @@
namespace Avalonia.Dialogs
{
internal static class ByteSizeHelper
{
private static readonly string[] Prefixes =
{
"B",
"KB",
"MB",
"GB",
"TB"
};
{
private static readonly string[] Prefixes =
{
"B",
"KB",
"MB",
"GB",
"TB"
};
public static string ToString(long bytes)
{
var index = 0;
while (bytes >= 1000)
{
bytes /= 1000;
++index;
}
return $"{bytes:N} {Prefixes[index]}";
}
}
public static string ToString(long bytes)
{
var index = 0;
while (bytes >= 1000)
{
bytes /= 1000;
++index;
}
return $"{bytes:N} {Prefixes[index]}";
}
}
}

24
src/Avalonia.Dialogs/ChildFitter.cs

@ -5,17 +5,17 @@ using Avalonia.Layout;
namespace Avalonia.Dialogs
{
internal class ChildFitter : Decorator
{
protected override Size MeasureOverride(Size availableSize)
{
return new Size(0, 0);
}
{
protected override Size MeasureOverride(Size availableSize)
{
return new Size(0, 0);
}
protected override Size ArrangeOverride(Size finalSize)
{
Child.Measure(finalSize);
base.ArrangeOverride(finalSize);
return finalSize;
}
}
protected override Size ArrangeOverride(Size finalSize)
{
Child.Measure(finalSize);
base.ArrangeOverride(finalSize);
return finalSize;
}
}
}

28
src/Avalonia.Dialogs/FileSizeStringConverter.cs

@ -7,20 +7,20 @@ using System.Text;
namespace Avalonia.Dialogs
{
internal class FileSizeStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if(value is long size && size > 0)
{
return ByteSizeHelper.ToString(size);
}
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is long size && size > 0)
{
return ByteSizeHelper.ToString(size);
}
return "";
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

4
src/Avalonia.Dialogs/ManagedFileChooser.xaml

@ -59,7 +59,7 @@
<Button Command="{Binding Cancel}">Cancel</Button>
</StackPanel>
</DockPanel>
<DropDown DockPanel.Dock="Bottom"
IsVisible="{Binding ShowFilters}"
Items="{Binding Filters}"
@ -67,7 +67,7 @@
Margin="0 5 0 0" />
<TextBox Text="{Binding FileName}" Watermark="File name" DockPanel.Dock="Bottom" IsVisible="{Binding !SelectingFolder}" />
<ListBox Margin="0 0 5 5" BorderBrush="Transparent" x:Name="QuickLinks" Items="{Binding QuickLinks}"
SelectedIndex="{Binding QuickLinksSelectedIndex}"
DockPanel.Dock="Left" Background="{DynamicResource ThemeControlMidBrush}" Focusable="False">

148
src/Avalonia.Dialogs/ManagedFileChooser.xaml.cs

@ -11,78 +11,78 @@ using Avalonia.Markup.Xaml;
namespace Avalonia.Dialogs
{
internal class ManagedFileChooser : UserControl
{
private Control _quickLinksRoot;
private ListBox _filesView;
public ManagedFileChooser()
{
AvaloniaXamlLoader.Load(this);
AddHandler(PointerPressedEvent, OnPointerPressed, RoutingStrategies.Tunnel);
_quickLinksRoot = this.FindControl<Control>("QuickLinks");
_filesView = this.FindControl<ListBox>("Files");
}
ManagedFileChooserViewModel Model => DataContext as ManagedFileChooserViewModel;
private void OnPointerPressed(object sender, PointerPressedEventArgs e)
{
var model = (e.Source as StyledElement)?.DataContext as ManagedFileChooserItemViewModel;
if (model == null)
{
return;
}
var isQuickLink = _quickLinksRoot.IsLogicalParentOf(e.Source as Control);
if (e.ClickCount == 2 || isQuickLink)
{
if (model.IsDirectory)
{
Model?.Navigate(model.Path);
}
else
{
Model?.SelectSingleFile(model);
}
e.Handled = true;
}
}
protected override async void OnDataContextChanged(EventArgs e)
{
base.OnDataContextChanged(e);
var model = (DataContext as ManagedFileChooserViewModel);
if (model == null)
{
return;
}
var preselected = model.SelectedItems.FirstOrDefault();
if (preselected == null)
{
return;
}
//Let everything to settle down and scroll to selected item
await Task.Delay(100);
if (preselected != model.SelectedItems.FirstOrDefault())
{
return;
}
// Workaround for ListBox bug, scroll to the previous file
var indexOfPreselected = model.Items.IndexOf(preselected);
if (indexOfPreselected > 1)
{
_filesView.ScrollIntoView(model.Items[indexOfPreselected - 1]);
}
}
}
{
private Control _quickLinksRoot;
private ListBox _filesView;
public ManagedFileChooser()
{
AvaloniaXamlLoader.Load(this);
AddHandler(PointerPressedEvent, OnPointerPressed, RoutingStrategies.Tunnel);
_quickLinksRoot = this.FindControl<Control>("QuickLinks");
_filesView = this.FindControl<ListBox>("Files");
}
ManagedFileChooserViewModel Model => DataContext as ManagedFileChooserViewModel;
private void OnPointerPressed(object sender, PointerPressedEventArgs e)
{
var model = (e.Source as StyledElement)?.DataContext as ManagedFileChooserItemViewModel;
if (model == null)
{
return;
}
var isQuickLink = _quickLinksRoot.IsLogicalParentOf(e.Source as Control);
if (e.ClickCount == 2 || isQuickLink)
{
if (model.IsDirectory)
{
Model?.Navigate(model.Path);
}
else
{
Model?.SelectSingleFile(model);
}
e.Handled = true;
}
}
protected override async void OnDataContextChanged(EventArgs e)
{
base.OnDataContextChanged(e);
var model = (DataContext as ManagedFileChooserViewModel);
if (model == null)
{
return;
}
var preselected = model.SelectedItems.FirstOrDefault();
if (preselected == null)
{
return;
}
//Let everything to settle down and scroll to selected item
await Task.Delay(100);
if (preselected != model.SelectedItems.FirstOrDefault())
{
return;
}
// Workaround for ListBox bug, scroll to the previous file
var indexOfPreselected = model.Items.IndexOf(preselected);
if (indexOfPreselected > 1)
{
_filesView.ScrollIntoView(model.Items[indexOfPreselected - 1]);
}
}
}
}

84
src/Avalonia.Dialogs/ManagedFileChooserFilterViewModel.cs

@ -5,46 +5,46 @@ using Avalonia.Controls;
namespace Avalonia.Dialogs
{
internal class ManagedFileChooserFilterViewModel : InternalViewModelBase
{
private readonly string[] _extensions;
public string Name { get; }
public ManagedFileChooserFilterViewModel(FileDialogFilter filter)
{
Name = filter.Name;
if (filter.Extensions.Contains("*"))
{
return;
}
_extensions = filter.Extensions?.Select(e => "." + e.ToLowerInvariant()).ToArray();
}
public ManagedFileChooserFilterViewModel()
{
Name = "All files";
}
public bool Match(string filename)
{
if (_extensions == null)
{
return true;
}
foreach (var ext in _extensions)
{
if (filename.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
}
return false;
}
public override string ToString() => Name;
}
internal class ManagedFileChooserFilterViewModel : InternalViewModelBase
{
private readonly string[] _extensions;
public string Name { get; }
public ManagedFileChooserFilterViewModel(FileDialogFilter filter)
{
Name = filter.Name;
if (filter.Extensions.Contains("*"))
{
return;
}
_extensions = filter.Extensions?.Select(e => "." + e.ToLowerInvariant()).ToArray();
}
public ManagedFileChooserFilterViewModel()
{
Name = "All files";
}
public bool Match(string filename)
{
if (_extensions == null)
{
return true;
}
foreach (var ext in _extensions)
{
if (filename.EndsWith(ext, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
}
return false;
}
public override string ToString() => Name;
}
}

108
src/Avalonia.Dialogs/ManagedFileChooserItemViewModel.cs

@ -3,67 +3,67 @@ using System;
namespace Avalonia.Dialogs
{
internal class ManagedFileChooserItemViewModel : InternalViewModelBase
{
private string _displayName;
private string _path;
private bool _isDirectory;
private DateTime _modified;
private string _type;
private long _size;
{
private string _displayName;
private string _path;
private bool _isDirectory;
private DateTime _modified;
private string _type;
private long _size;
public string DisplayName
{
get => _displayName;
set => this.RaiseAndSetIfChanged(ref _displayName, value);
}
public string DisplayName
{
get => _displayName;
set => this.RaiseAndSetIfChanged(ref _displayName, value);
}
public string Path
{
get => _path;
set => this.RaiseAndSetIfChanged(ref _path, value);
}
public string Path
{
get => _path;
set => this.RaiseAndSetIfChanged(ref _path, value);
}
public DateTime Modified
{
get => _modified;
set => this.RaiseAndSetIfChanged(ref _modified, value);
}
public DateTime Modified
{
get => _modified;
set => this.RaiseAndSetIfChanged(ref _modified, value);
}
public string Type
{
get => _type;
set => this.RaiseAndSetIfChanged(ref _type, value);
}
public string Type
{
get => _type;
set => this.RaiseAndSetIfChanged(ref _type, value);
}
public long Size
{
get => _size;
set => this.RaiseAndSetIfChanged(ref _size, value);
}
public long Size
{
get => _size;
set => this.RaiseAndSetIfChanged(ref _size, value);
}
public string IconKey => IsDirectory ? "Icon_Folder" : "Icon_File";
public string IconKey => IsDirectory ? "Icon_Folder" : "Icon_File";
public bool IsDirectory
{
get => _isDirectory;
set
{
if (this.RaiseAndSetIfChanged(ref _isDirectory, value))
{
this.RaisePropertyChanged(nameof(IconKey));
}
}
}
public bool IsDirectory
{
get => _isDirectory;
set
{
if (this.RaiseAndSetIfChanged(ref _isDirectory, value))
{
this.RaisePropertyChanged(nameof(IconKey));
}
}
}
public ManagedFileChooserItemViewModel()
{
}
public ManagedFileChooserItemViewModel()
{
}
public ManagedFileChooserItemViewModel(ManagedFileChooserNavigationItem item)
{
IsDirectory = true;
Path = item.Path;
DisplayName = item.DisplayName;
}
}
public ManagedFileChooserItemViewModel(ManagedFileChooserNavigationItem item)
{
IsDirectory = true;
Path = item.Path;
DisplayName = item.DisplayName;
}
}
}

8
src/Avalonia.Dialogs/ManagedFileChooserNavigationItem.cs

@ -1,8 +1,8 @@
namespace Avalonia.Dialogs
{
internal class ManagedFileChooserNavigationItem
{
public string DisplayName { get; set; }
public string Path { get; set; }
}
{
public string DisplayName { get; set; }
public string Path { get; set; }
}
}

142
src/Avalonia.Dialogs/ManagedFileChooserSources.cs

@ -6,84 +6,84 @@ using System.Runtime.InteropServices;
namespace Avalonia.Dialogs
{
internal class ManagedFileChooserSources
{
public Func<ManagedFileChooserNavigationItem[]> GetUserDirectories { get; set; }
= DefaultGetUserDirectories;
{
public Func<ManagedFileChooserNavigationItem[]> GetUserDirectories { get; set; }
= DefaultGetUserDirectories;
public Func<ManagedFileChooserNavigationItem[]> GetFileSystemRoots { get; set; }
= DefaultGetFileSystemRoots;
public Func<ManagedFileChooserNavigationItem[]> GetFileSystemRoots { get; set; }
= DefaultGetFileSystemRoots;
public Func<ManagedFileChooserSources, ManagedFileChooserNavigationItem[]> GetAllItemsDelegate { get; set; }
= DefaultGetAllItems;
public Func<ManagedFileChooserSources, ManagedFileChooserNavigationItem[]> GetAllItemsDelegate { get; set; }
= DefaultGetAllItems;
public ManagedFileChooserNavigationItem[] GetAllItems() => GetAllItemsDelegate(this);
public ManagedFileChooserNavigationItem[] GetAllItems() => GetAllItemsDelegate(this);
public static ManagedFileChooserNavigationItem[] DefaultGetAllItems(ManagedFileChooserSources sources)
{
return sources.GetUserDirectories().Concat(sources.GetFileSystemRoots()).ToArray();
}
public static ManagedFileChooserNavigationItem[] DefaultGetAllItems(ManagedFileChooserSources sources)
{
return sources.GetUserDirectories().Concat(sources.GetFileSystemRoots()).ToArray();
}
private static Environment.SpecialFolder[] s_folders = new[]
{
Environment.SpecialFolder.Desktop,
Environment.SpecialFolder.UserProfile,
Environment.SpecialFolder.MyDocuments,
Environment.SpecialFolder.MyMusic,
Environment.SpecialFolder.MyPictures,
Environment.SpecialFolder.MyVideos
};
private static Environment.SpecialFolder[] s_folders = new[]
{
Environment.SpecialFolder.Desktop,
Environment.SpecialFolder.UserProfile,
Environment.SpecialFolder.MyDocuments,
Environment.SpecialFolder.MyMusic,
Environment.SpecialFolder.MyPictures,
Environment.SpecialFolder.MyVideos
};
public static ManagedFileChooserNavigationItem[] DefaultGetUserDirectories()
{
return s_folders.Select(Environment.GetFolderPath).Distinct()
.Where(d => !string.IsNullOrWhiteSpace(d))
.Where(Directory.Exists)
.Select(d => new ManagedFileChooserNavigationItem
{
Path = d,
DisplayName = Path.GetFileName(d)
}).ToArray();
}
public static ManagedFileChooserNavigationItem[] DefaultGetUserDirectories()
{
return s_folders.Select(Environment.GetFolderPath).Distinct()
.Where(d => !string.IsNullOrWhiteSpace(d))
.Where(Directory.Exists)
.Select(d => new ManagedFileChooserNavigationItem
{
Path = d,
DisplayName = Path.GetFileName(d)
}).ToArray();
}
public static ManagedFileChooserNavigationItem[] DefaultGetFileSystemRoots()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return DriveInfo.GetDrives().Select(d => new ManagedFileChooserNavigationItem
{
DisplayName = d.Name,
Path = d.RootDirectory.FullName
}).ToArray();
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
var paths = Directory.GetDirectories("/Volumes");
return paths.Select(x => new ManagedFileChooserNavigationItem
{
DisplayName = Path.GetFileName(x),
Path = x
}).ToArray();
}
else
{
var paths = Directory.GetDirectories("/media/");
public static ManagedFileChooserNavigationItem[] DefaultGetFileSystemRoots()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return DriveInfo.GetDrives().Select(d => new ManagedFileChooserNavigationItem
{
DisplayName = d.Name,
Path = d.RootDirectory.FullName
}).ToArray();
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
var paths = Directory.GetDirectories("/Volumes");
var drives = new ManagedFileChooserNavigationItem[]
{
new ManagedFileChooserNavigationItem
{
DisplayName = "File System",
Path = "/"
}
}.Concat(paths.Select(x => new ManagedFileChooserNavigationItem
{
DisplayName = Path.GetFileName(x),
Path = x
})).ToArray();
return paths.Select(x => new ManagedFileChooserNavigationItem
{
DisplayName = Path.GetFileName(x),
Path = x
}).ToArray();
}
else
{
var paths = Directory.GetDirectories("/media/");
return drives;
}
}
}
var drives = new ManagedFileChooserNavigationItem[]
{
new ManagedFileChooserNavigationItem
{
DisplayName = "File System",
Path = "/"
}
}.Concat(paths.Select(x => new ManagedFileChooserNavigationItem
{
DisplayName = Path.GetFileName(x),
Path = x
})).ToArray();
return drives;
}
}
}
}

614
src/Avalonia.Dialogs/ManagedFileChooserViewModel.cs

@ -10,142 +10,142 @@ using Avalonia.Threading;
namespace Avalonia.Dialogs
{
internal class ManagedFileChooserViewModel : InternalViewModelBase
{
public event Action CancelRequested;
public event Action<string[]> CompleteRequested;
public AvaloniaList<ManagedFileChooserItemViewModel> QuickLinks { get; } =
new AvaloniaList<ManagedFileChooserItemViewModel>();
public AvaloniaList<ManagedFileChooserItemViewModel> Items { get; } =
new AvaloniaList<ManagedFileChooserItemViewModel>();
public AvaloniaList<ManagedFileChooserFilterViewModel> Filters { get; } =
new AvaloniaList<ManagedFileChooserFilterViewModel>();
public AvaloniaList<ManagedFileChooserItemViewModel> SelectedItems { get; } =
new AvaloniaList<ManagedFileChooserItemViewModel>();
string _location;
string _fileName;
private bool _showHiddenFiles;
private ManagedFileChooserFilterViewModel _selectedFilter;
private bool _selectingDirectory;
private bool _savingFile;
private bool _scheduledSelectionValidation;
private string _defaultExtension;
public string Location
{
get => _location;
private set => this.RaiseAndSetIfChanged(ref _location, value);
}
public string FileName
{
get => _fileName;
private set => this.RaiseAndSetIfChanged(ref _fileName, value);
}
public bool SelectingFolder => _selectingDirectory;
public bool ShowFilters { get; }
public SelectionMode SelectionMode { get; }
public string Title { get; }
public int QuickLinksSelectedIndex
{
get
{
for (var index = 0; index < QuickLinks.Count; index++)
{
var i = QuickLinks[index];
if (i.Path == Location)
{
return index;
}
}
return -1;
}
set => this.RaisePropertyChanged(nameof(QuickLinksSelectedIndex));
}
public ManagedFileChooserFilterViewModel SelectedFilter
{
get => _selectedFilter;
set
{
this.RaiseAndSetIfChanged(ref _selectedFilter, value);
Refresh();
}
}
public bool ShowHiddenFiles
{
get => _showHiddenFiles;
set
{
this.RaiseAndSetIfChanged(ref _showHiddenFiles, value);
Refresh();
}
}
public ManagedFileChooserViewModel(FileSystemDialog dialog)
{
var quickSources = AvaloniaLocator.Current.GetService<ManagedFileChooserSources>()
?? new ManagedFileChooserSources();
QuickLinks.Clear();
QuickLinks.AddRange(quickSources.GetAllItems().Select(i => new ManagedFileChooserItemViewModel(i)));
Title = dialog.Title ?? (
dialog is OpenFileDialog ? "Open file"
: dialog is SaveFileDialog ? "Save file"
: dialog is OpenFolderDialog ? "Select directory"
: throw new ArgumentException(nameof(dialog)));
var directory = dialog.InitialDirectory;
if (directory == null || !Directory.Exists(directory))
{
directory = Directory.GetCurrentDirectory();
}
if (dialog is FileDialog fd)
{
if (fd.Filters?.Count > 0)
{
Filters.AddRange(fd.Filters.Select(f => new ManagedFileChooserFilterViewModel(f)));
_selectedFilter = Filters[0];
ShowFilters = true;
}
if (dialog is OpenFileDialog ofd)
{
if (ofd.AllowMultiple)
{
SelectionMode = SelectionMode.Multiple;
}
}
}
_selectingDirectory = dialog is OpenFolderDialog;
if(dialog is SaveFileDialog sfd)
{
_savingFile = true;
_defaultExtension = sfd.DefaultExtension;
FileName = sfd.InitialFileName;
}
Navigate(directory, (dialog as FileDialog)?.InitialFileName);
SelectedItems.CollectionChanged += OnSelectionChangedAsync;
}
public void EnterPressed ()
{
public event Action CancelRequested;
public event Action<string[]> CompleteRequested;
public AvaloniaList<ManagedFileChooserItemViewModel> QuickLinks { get; } =
new AvaloniaList<ManagedFileChooserItemViewModel>();
public AvaloniaList<ManagedFileChooserItemViewModel> Items { get; } =
new AvaloniaList<ManagedFileChooserItemViewModel>();
public AvaloniaList<ManagedFileChooserFilterViewModel> Filters { get; } =
new AvaloniaList<ManagedFileChooserFilterViewModel>();
public AvaloniaList<ManagedFileChooserItemViewModel> SelectedItems { get; } =
new AvaloniaList<ManagedFileChooserItemViewModel>();
string _location;
string _fileName;
private bool _showHiddenFiles;
private ManagedFileChooserFilterViewModel _selectedFilter;
private bool _selectingDirectory;
private bool _savingFile;
private bool _scheduledSelectionValidation;
private string _defaultExtension;
public string Location
{
get => _location;
private set => this.RaiseAndSetIfChanged(ref _location, value);
}
public string FileName
{
get => _fileName;
private set => this.RaiseAndSetIfChanged(ref _fileName, value);
}
public bool SelectingFolder => _selectingDirectory;
public bool ShowFilters { get; }
public SelectionMode SelectionMode { get; }
public string Title { get; }
public int QuickLinksSelectedIndex
{
get
{
for (var index = 0; index < QuickLinks.Count; index++)
{
var i = QuickLinks[index];
if (i.Path == Location)
{
return index;
}
}
return -1;
}
set => this.RaisePropertyChanged(nameof(QuickLinksSelectedIndex));
}
public ManagedFileChooserFilterViewModel SelectedFilter
{
get => _selectedFilter;
set
{
this.RaiseAndSetIfChanged(ref _selectedFilter, value);
Refresh();
}
}
public bool ShowHiddenFiles
{
get => _showHiddenFiles;
set
{
this.RaiseAndSetIfChanged(ref _showHiddenFiles, value);
Refresh();
}
}
public ManagedFileChooserViewModel(FileSystemDialog dialog)
{
var quickSources = AvaloniaLocator.Current.GetService<ManagedFileChooserSources>()
?? new ManagedFileChooserSources();
QuickLinks.Clear();
QuickLinks.AddRange(quickSources.GetAllItems().Select(i => new ManagedFileChooserItemViewModel(i)));
Title = dialog.Title ?? (
dialog is OpenFileDialog ? "Open file"
: dialog is SaveFileDialog ? "Save file"
: dialog is OpenFolderDialog ? "Select directory"
: throw new ArgumentException(nameof(dialog)));
var directory = dialog.InitialDirectory;
if (directory == null || !Directory.Exists(directory))
{
directory = Directory.GetCurrentDirectory();
}
if (dialog is FileDialog fd)
{
if (fd.Filters?.Count > 0)
{
Filters.AddRange(fd.Filters.Select(f => new ManagedFileChooserFilterViewModel(f)));
_selectedFilter = Filters[0];
ShowFilters = true;
}
if (dialog is OpenFileDialog ofd)
{
if (ofd.AllowMultiple)
{
SelectionMode = SelectionMode.Multiple;
}
}
}
_selectingDirectory = dialog is OpenFolderDialog;
if (dialog is SaveFileDialog sfd)
{
_savingFile = true;
_defaultExtension = sfd.DefaultExtension;
FileName = sfd.InitialFileName;
}
Navigate(directory, (dialog as FileDialog)?.InitialFileName);
SelectedItems.CollectionChanged += OnSelectionChangedAsync;
}
public void EnterPressed()
{
if (Directory.Exists(Location))
{
@ -157,177 +157,177 @@ namespace Avalonia.Dialogs
}
}
private async void OnSelectionChangedAsync(object sender, NotifyCollectionChangedEventArgs e)
{
if (_scheduledSelectionValidation)
{
return;
}
_scheduledSelectionValidation = true;
await Dispatcher.UIThread.InvokeAsync(() =>
{
try
{
if (_selectingDirectory)
{
SelectedItems.Clear();
}
else
{
var invalidItems = SelectedItems.Where(i => i.IsDirectory).ToList();
foreach (var item in invalidItems)
{
SelectedItems.Remove(item);
}
if(!_selectingDirectory)
{
FileName = SelectedItems.FirstOrDefault()?.DisplayName;
}
}
}
finally
{
_scheduledSelectionValidation = false;
}
});
}
void NavigateRoot(string initialSelectionName)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Navigate(Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.System)), initialSelectionName);
}
else
{
Navigate("/", initialSelectionName);
}
}
public void Refresh() => Navigate(Location);
public void Navigate(string path, string initialSelectionName = null)
{
if (!Directory.Exists(path))
{
NavigateRoot(initialSelectionName);
}
else
{
Location = path;
Items.Clear();
SelectedItems.Clear();
try
{
var infos = new DirectoryInfo(path).EnumerateFileSystemInfos();
if (!ShowHiddenFiles)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
infos = infos.Where(i => (i.Attributes & (FileAttributes.Hidden | FileAttributes.System)) != 0);
}
else
{
infos = infos.Where(i => !i.Name.StartsWith("."));
}
}
if (SelectedFilter != null)
{
infos = infos.Where(i => i is DirectoryInfo || SelectedFilter.Match(i.Name));
}
Items.AddRange(infos.Where(x =>
{
if (_selectingDirectory)
{
if (!(x is DirectoryInfo))
{
return false;
}
}
return true;
})
private async void OnSelectionChangedAsync(object sender, NotifyCollectionChangedEventArgs e)
{
if (_scheduledSelectionValidation)
{
return;
}
_scheduledSelectionValidation = true;
await Dispatcher.UIThread.InvokeAsync(() =>
{
try
{
if (_selectingDirectory)
{
SelectedItems.Clear();
}
else
{
var invalidItems = SelectedItems.Where(i => i.IsDirectory).ToList();
foreach (var item in invalidItems)
{
SelectedItems.Remove(item);
}
if (!_selectingDirectory)
{
FileName = SelectedItems.FirstOrDefault()?.DisplayName;
}
}
}
finally
{
_scheduledSelectionValidation = false;
}
});
}
void NavigateRoot(string initialSelectionName)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
Navigate(Path.GetPathRoot(Environment.GetFolderPath(Environment.SpecialFolder.System)), initialSelectionName);
}
else
{
Navigate("/", initialSelectionName);
}
}
public void Refresh() => Navigate(Location);
public void Navigate(string path, string initialSelectionName = null)
{
if (!Directory.Exists(path))
{
NavigateRoot(initialSelectionName);
}
else
{
Location = path;
Items.Clear();
SelectedItems.Clear();
try
{
var infos = new DirectoryInfo(path).EnumerateFileSystemInfos();
if (!ShowHiddenFiles)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
infos = infos.Where(i => (i.Attributes & (FileAttributes.Hidden | FileAttributes.System)) != 0);
}
else
{
infos = infos.Where(i => !i.Name.StartsWith("."));
}
}
if (SelectedFilter != null)
{
infos = infos.Where(i => i is DirectoryInfo || SelectedFilter.Match(i.Name));
}
Items.AddRange(infos.Where(x =>
{
if (_selectingDirectory)
{
if (!(x is DirectoryInfo))
{
return false;
}
}
return true;
})
.Where(x => x.Exists)
.Select(info => new ManagedFileChooserItemViewModel
{
DisplayName = info.Name,
Path = info.FullName,
IsDirectory = info is DirectoryInfo,
Type = info is FileInfo ? info.Extension : "File Folder",
Size = info is FileInfo f ? f.Length : 0,
Modified = info.LastWriteTime
})
.OrderByDescending(x => x.IsDirectory)
.ThenBy(x => x.DisplayName, StringComparer.InvariantCultureIgnoreCase));
if (initialSelectionName != null)
{
var sel = Items.FirstOrDefault(i => !i.IsDirectory && i.DisplayName == initialSelectionName);
if (sel != null)
{
SelectedItems.Add(sel);
}
}
this.RaisePropertyChanged(nameof(QuickLinksSelectedIndex));
}
catch (System.UnauthorizedAccessException)
{
}
}
}
public void GoUp()
{
var parent = Path.GetDirectoryName(Location);
if (string.IsNullOrWhiteSpace(parent))
{
return;
}
Navigate(parent);
}
public void Cancel()
{
CancelRequested?.Invoke();
}
public void Ok()
{
if (_selectingDirectory)
{
CompleteRequested?.Invoke(new[] { Location });
}
else if(_savingFile)
{
if (!string.IsNullOrWhiteSpace(FileName))
{
if (!Path.HasExtension(FileName) && !string.IsNullOrWhiteSpace(_defaultExtension))
{
FileName = Path.ChangeExtension(FileName, _defaultExtension);
}
CompleteRequested?.Invoke(new[] { Path.Combine(Location, FileName) });
}
}
else
{
CompleteRequested?.Invoke(SelectedItems.Select(i => i.Path).ToArray());
}
}
public void SelectSingleFile(ManagedFileChooserItemViewModel item)
{
CompleteRequested?.Invoke(new[] { item.Path });
}
}
{
DisplayName = info.Name,
Path = info.FullName,
IsDirectory = info is DirectoryInfo,
Type = info is FileInfo ? info.Extension : "File Folder",
Size = info is FileInfo f ? f.Length : 0,
Modified = info.LastWriteTime
})
.OrderByDescending(x => x.IsDirectory)
.ThenBy(x => x.DisplayName, StringComparer.InvariantCultureIgnoreCase));
if (initialSelectionName != null)
{
var sel = Items.FirstOrDefault(i => !i.IsDirectory && i.DisplayName == initialSelectionName);
if (sel != null)
{
SelectedItems.Add(sel);
}
}
this.RaisePropertyChanged(nameof(QuickLinksSelectedIndex));
}
catch (System.UnauthorizedAccessException)
{
}
}
}
public void GoUp()
{
var parent = Path.GetDirectoryName(Location);
if (string.IsNullOrWhiteSpace(parent))
{
return;
}
Navigate(parent);
}
public void Cancel()
{
CancelRequested?.Invoke();
}
public void Ok()
{
if (_selectingDirectory)
{
CompleteRequested?.Invoke(new[] { Location });
}
else if (_savingFile)
{
if (!string.IsNullOrWhiteSpace(FileName))
{
if (!Path.HasExtension(FileName) && !string.IsNullOrWhiteSpace(_defaultExtension))
{
FileName = Path.ChangeExtension(FileName, _defaultExtension);
}
CompleteRequested?.Invoke(new[] { Path.Combine(Location, FileName) });
}
}
else
{
CompleteRequested?.Invoke(SelectedItems.Select(i => i.Path).ToArray());
}
}
public void SelectSingleFile(ManagedFileChooserItemViewModel item)
{
CompleteRequested?.Invoke(new[] { item.Path });
}
}
}

16
src/Avalonia.Dialogs/ManagedFileDialogExtensions.cs

@ -9,8 +9,8 @@ using Avalonia.Platform;
namespace Avalonia.Dialogs
{
public static class ManagedFileDialogExtensions
{
public static class ManagedFileDialogExtensions
{
class ManagedSystemDialogImpl<T> : ISystemDialogImpl where T : Window, new()
{
async Task<string[]> Show(SystemDialog d, IWindowImpl parent)
@ -47,12 +47,12 @@ namespace Avalonia.Dialogs
}
public static TAppBuilder UseManagedSystemDialogs<TAppBuilder>(this TAppBuilder builder)
where TAppBuilder : AppBuilderBase<TAppBuilder>, new()
{
builder.AfterSetup(_ =>
AvaloniaLocator.CurrentMutable.Bind<ISystemDialogImpl>().ToSingleton<ManagedSystemDialogImpl<Window>>());
return builder;
}
where TAppBuilder : AppBuilderBase<TAppBuilder>, new()
{
builder.AfterSetup(_ =>
AvaloniaLocator.CurrentMutable.Bind<ISystemDialogImpl>().ToSingleton<ManagedSystemDialogImpl<Window>>());
return builder;
}
public static TAppBuilder UseManagedSystemDialogs<TAppBuilder, TWindow>(this TAppBuilder builder)
where TAppBuilder : AppBuilderBase<TAppBuilder>, new() where TWindow : Window, new()

22
src/Avalonia.Dialogs/ResourceSelectorConverter.cs

@ -6,16 +6,16 @@ using Avalonia.Data.Converters;
namespace Avalonia.Dialogs
{
internal class ResourceSelectorConverter : ResourceDictionary, IValueConverter
{
public object Convert(object key, Type targetType, object parameter, CultureInfo culture)
{
TryGetResource((string)key, out var value);
return value;
}
{
public object Convert(object key, Type targetType, object parameter, CultureInfo culture)
{
TryGetResource((string)key, out var value);
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

Loading…
Cancel
Save