diff --git a/src/Files.App/Helpers/Navigation/NavigationHelpers.cs b/src/Files.App/Helpers/Navigation/NavigationHelpers.cs index ff20b34c023d..c390ecd40a43 100644 --- a/src/Files.App/Helpers/Navigation/NavigationHelpers.cs +++ b/src/Files.App/Helpers/Navigation/NavigationHelpers.cs @@ -211,7 +211,7 @@ private static async Task UpdateTabInfoAsync(TabBarItem tabItem, object navigati return (tabLocationHeader, iconSource, toolTipText); } - public static async Task UpdateInstancePropertiesAsync(object navigationArg) + public static async Task UpdateInstancePropertiesAsync(object? navigationArg) { await SafetyExtensions.IgnoreExceptions(async () => { diff --git a/src/Files.App/UserControls/AddressToolbar.xaml.cs b/src/Files.App/UserControls/AddressToolbar.xaml.cs index dd1936de1880..8e15b248957f 100644 --- a/src/Files.App/UserControls/AddressToolbar.xaml.cs +++ b/src/Files.App/UserControls/AddressToolbar.xaml.cs @@ -46,7 +46,7 @@ public bool ShowSearchBox // Using a DependencyProperty as the backing store for ViewModel. This enables animation, styling, binding, etc... public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(ToolbarViewModel), typeof(AddressToolbar), new PropertyMetadata(null)); - public ToolbarViewModel ViewModel + public ToolbarViewModel? ViewModel { get => (ToolbarViewModel)GetValue(ViewModelProperty); set => SetValue(ViewModelProperty, value); diff --git a/src/Files.App/UserControls/InnerNavigationToolbar.xaml.cs b/src/Files.App/UserControls/InnerNavigationToolbar.xaml.cs index 52a1d1f4f4ac..ba228183a259 100644 --- a/src/Files.App/UserControls/InnerNavigationToolbar.xaml.cs +++ b/src/Files.App/UserControls/InnerNavigationToolbar.xaml.cs @@ -27,7 +27,7 @@ public InnerNavigationToolbar() public AppModel AppModel => App.AppModel; - public ToolbarViewModel ViewModel + public ToolbarViewModel? ViewModel { get => (ToolbarViewModel)GetValue(ViewModelProperty); set => SetValue(ViewModelProperty, value); diff --git a/src/Files.App/UserControls/StatusBarControl.xaml.cs b/src/Files.App/UserControls/StatusBarControl.xaml.cs index b0a62bd8d962..9dc177300003 100644 --- a/src/Files.App/UserControls/StatusBarControl.xaml.cs +++ b/src/Files.App/UserControls/StatusBarControl.xaml.cs @@ -21,7 +21,7 @@ public DirectoryPropertiesViewModel? DirectoryPropertiesViewModel public static readonly DependencyProperty DirectoryPropertiesViewModelProperty = DependencyProperty.Register(nameof(DirectoryPropertiesViewModel), typeof(DirectoryPropertiesViewModel), typeof(StatusBarControl), new PropertyMetadata(null)); - public SelectedItemsPropertiesViewModel SelectedItemsPropertiesViewModel + public SelectedItemsPropertiesViewModel? SelectedItemsPropertiesViewModel { get => (SelectedItemsPropertiesViewModel)GetValue(SelectedItemsPropertiesViewModelProperty); set => SetValue(SelectedItemsPropertiesViewModelProperty, value); diff --git a/src/Files.App/Utils/RecycleBin/RecycleBinHelpers.cs b/src/Files.App/Utils/RecycleBin/RecycleBinHelpers.cs index 1adc6d2ff364..c8e088b6f761 100644 --- a/src/Files.App/Utils/RecycleBin/RecycleBinHelpers.cs +++ b/src/Files.App/Utils/RecycleBin/RecycleBinHelpers.cs @@ -117,10 +117,14 @@ public static async Task RestoreRecycleBinAsync() public static async Task RestoreSelectionRecycleBinAsync(IShellPage associatedInstance) { + var items = associatedInstance.SlimContentPage.SelectedItems; + if (items == null) + return; var ConfirmEmptyBinDialog = new ContentDialog() { Title = "ConfirmRestoreSelectionBinDialogTitle".GetLocalizedResource(), - Content = string.Format("ConfirmRestoreSelectionBinDialogContent".GetLocalizedResource(), associatedInstance.SlimContentPage.SelectedItems.Count), + + Content = string.Format("ConfirmRestoreSelectionBinDialogContent".GetLocalizedResource(), items.Count), PrimaryButtonText = "Yes".GetLocalizedResource(), SecondaryButtonText = "Cancel".GetLocalizedResource(), DefaultButton = ContentDialogButton.Primary @@ -152,7 +156,10 @@ public static bool RecycleBinHasItems() public static async Task RestoreItemAsync(IShellPage associatedInstance) { - var items = associatedInstance.SlimContentPage.SelectedItems.ToList().Where(x => x is RecycleBinItem).Select((item) => new + var selected = associatedInstance.SlimContentPage.SelectedItems; + if (selected == null) + return; + var items = selected.ToList().Where(x => x is RecycleBinItem).Select((item) => new { Source = StorageHelpers.FromPathAndType( item.ItemPath, @@ -164,10 +171,13 @@ public static async Task RestoreItemAsync(IShellPage associatedInstance) public static async Task DeleteItemAsync(IShellPage associatedInstance) { - var items = associatedInstance.SlimContentPage.SelectedItems.ToList().Select((item) => StorageHelpers.FromPathAndType( + var selected = associatedInstance.SlimContentPage.SelectedItems; + if (selected == null) + return; + var items = selected.ToList().Select((item) => StorageHelpers.FromPathAndType( item.ItemPath, item.PrimaryItemAttribute == StorageItemTypes.File ? FilesystemItemType.File : FilesystemItemType.Directory)); await associatedInstance.FilesystemHelpers.DeleteItemsAsync(items, userSettingsService.FoldersSettingsService.DeleteConfirmationPolicy, false, true); } } -} \ No newline at end of file +} diff --git a/src/Files.App/Utils/Storage/History/StorageHistoryWrapper.cs b/src/Files.App/Utils/Storage/History/StorageHistoryWrapper.cs index 4ef992a6bfb1..caec37180ff0 100644 --- a/src/Files.App/Utils/Storage/History/StorageHistoryWrapper.cs +++ b/src/Files.App/Utils/Storage/History/StorageHistoryWrapper.cs @@ -14,7 +14,7 @@ public class StorageHistoryWrapper : IDisposable public IStorageHistory GetCurrentHistory() => histories[index]; - public void AddHistory(IStorageHistory history) + public void AddHistory(IStorageHistory? history) { if (history is not null) { diff --git a/src/Files.App/Utils/Storage/Operations/FilesystemHelpers.cs b/src/Files.App/Utils/Storage/Operations/FilesystemHelpers.cs index 525f952c0b58..e774bccdfa71 100644 --- a/src/Files.App/Utils/Storage/Operations/FilesystemHelpers.cs +++ b/src/Files.App/Utils/Storage/Operations/FilesystemHelpers.cs @@ -25,7 +25,7 @@ public sealed class FilesystemHelpers : IFilesystemHelpers private readonly IJumpListService jumpListService; private IFilesystemOperations filesystemOperations; - private ItemManipulationModel itemManipulationModel => associatedInstance.SlimContentPage?.ItemManipulationModel; + private ItemManipulationModel? itemManipulationModel => associatedInstance.SlimContentPage?.ItemManipulationModel; private readonly CancellationToken cancellationToken; private static char[] RestrictedCharacters @@ -58,7 +58,7 @@ public FilesystemHelpers(IShellPage associatedInstance, CancellationToken cancel jumpListService = Ioc.Default.GetRequiredService(); filesystemOperations = new ShellFilesystemOperations(this.associatedInstance); } - public async Task<(ReturnResult, IStorageItem)> CreateAsync(IStorageItemWithPath source, bool registerHistory) + public async Task<(ReturnResult, IStorageItem?)> CreateAsync(IStorageItemWithPath source, bool registerHistory) { var returnStatus = ReturnResult.InProgress; var progress = new Progress(); @@ -363,7 +363,7 @@ public async Task CopyItemsFromClipboard(DataPackageView packageVi ReturnResult returnStatus = ReturnResult.InProgress; var destinations = new List(); - List binItems = null; + List? binItems = null; foreach (var item in source) { if (RecycleBinHelpers.IsPathUnderRecycleBin(item.Path)) @@ -511,7 +511,7 @@ public async Task MoveItemsFromClipboard(DataPackageView packageVi ReturnResult returnStatus = ReturnResult.InProgress; var destinations = new List(); - List binItems = null; + List? binItems = null; foreach (var item in source) { if (RecycleBinHelpers.IsPathUnderRecycleBin(item.Path)) @@ -551,7 +551,7 @@ await DialogDisplayHelper.ShowDialogAsync( return ReturnResult.Failed; } - IStorageHistory history = null; + IStorageHistory? history = null; switch (source.ItemType) { @@ -658,7 +658,8 @@ public static bool IsValidForFilename(string name) { var itemPathOrName = string.IsNullOrEmpty(item.src.Path) ? item.src.Item.Name : item.src.Path; incomingItems.Add(new FileSystemDialogConflictItemViewModel() { ConflictResolveOption = FileNameConflictResolveOptionType.None, SourcePath = itemPathOrName, DestinationPath = item.dest, DestinationDisplayName = Path.GetFileName(item.dest) }); - if (collisions.ContainsKey(incomingItems.ElementAt(item.index).SourcePath)) + var path = incomingItems.ElementAt(item.index).SourcePath; + if (path is not null && collisions.ContainsKey(path)) { // Something strange happened, log App.Logger.LogWarning($"Duplicate key when resolving conflicts: {incomingItems.ElementAt(item.index).SourcePath}, {item.src.Name}\n" + @@ -870,6 +871,8 @@ public void Dispose() { filesystemOperations?.Dispose(); + // SUPPRESS: Cannot convert null literal to non-nullable reference type. + #pragma warning disable CS8625 associatedInstance = null; filesystemOperations = null; } diff --git a/src/Files.App/Utils/Storage/Operations/IFilesystemHelpers.cs b/src/Files.App/Utils/Storage/Operations/IFilesystemHelpers.cs index 204e592b7434..ad0c29bf3c48 100644 --- a/src/Files.App/Utils/Storage/Operations/IFilesystemHelpers.cs +++ b/src/Files.App/Utils/Storage/Operations/IFilesystemHelpers.cs @@ -14,7 +14,7 @@ public interface IFilesystemHelpers : IDisposable /// FullPath to the item /// Determines whether is saved /// of performed operation - Task<(ReturnResult, IStorageItem)> CreateAsync(IStorageItemWithPath source, bool registerHistory); + Task<(ReturnResult, IStorageItem?)> CreateAsync(IStorageItemWithPath source, bool registerHistory); #region Delete diff --git a/src/Files.App/ViewModels/UserControls/SidebarViewModel.cs b/src/Files.App/ViewModels/UserControls/SidebarViewModel.cs index e09e30279717..8c017af8628e 100644 --- a/src/Files.App/ViewModels/UserControls/SidebarViewModel.cs +++ b/src/Files.App/ViewModels/UserControls/SidebarViewModel.cs @@ -88,14 +88,14 @@ public SidebarDisplayMode SidebarDisplayMode public bool IsSidebarCompactSize => SidebarDisplayMode == SidebarDisplayMode.Compact || SidebarDisplayMode == SidebarDisplayMode.Minimal; - public void NotifyInstanceRelatedPropertiesChanged(string arg) + public void NotifyInstanceRelatedPropertiesChanged(string? arg) { UpdateSidebarSelectedItemFromArgs(arg); OnPropertyChanged(nameof(SidebarSelectedItem)); } - public void UpdateSidebarSelectedItemFromArgs(string arg) + public void UpdateSidebarSelectedItemFromArgs(string? arg) { var value = arg; diff --git a/src/Files.App/Views/MainPage.xaml.cs b/src/Files.App/Views/MainPage.xaml.cs index e47b1e0359e1..efd0901de528 100644 --- a/src/Files.App/Views/MainPage.xaml.cs +++ b/src/Files.App/Views/MainPage.xaml.cs @@ -161,7 +161,7 @@ public async void TabItemContent_ContentChanged(object? sender, CustomTabViewIte var paneArgs = e.NavigationParameter as PaneNavigationArguments; SidebarAdaptiveViewModel.UpdateSidebarSelectedItemFromArgs(SidebarAdaptiveViewModel.PaneHolder.IsLeftPaneActive ? - paneArgs.LeftPaneNavPathParam : paneArgs.RightPaneNavPathParam); + paneArgs?.LeftPaneNavPathParam : paneArgs?.RightPaneNavPathParam); UpdateStatusBarProperties(); LoadPaneChanged(); @@ -175,9 +175,12 @@ public void MultitaskingControl_CurrentInstanceChanged(object? sender, CurrentIn SidebarAdaptiveViewModel.PaneHolder.PropertyChanged -= PaneHolder_PropertyChanged; var navArgs = e.CurrentInstance.TabItemParameter?.NavigationParameter; - SidebarAdaptiveViewModel.PaneHolder = e.CurrentInstance as IPaneHolder; - SidebarAdaptiveViewModel.PaneHolder.PropertyChanged += PaneHolder_PropertyChanged; - SidebarAdaptiveViewModel.NotifyInstanceRelatedPropertiesChanged((navArgs as PaneNavigationArguments).LeftPaneNavPathParam); + if (e.CurrentInstance is IPaneHolder currentInstance) + { + SidebarAdaptiveViewModel.PaneHolder = currentInstance; + SidebarAdaptiveViewModel.PaneHolder.PropertyChanged += PaneHolder_PropertyChanged; + } + SidebarAdaptiveViewModel.NotifyInstanceRelatedPropertiesChanged((navArgs as PaneNavigationArguments)?.LeftPaneNavPathParam); if (SidebarAdaptiveViewModel.PaneHolder?.ActivePaneOrColumn.SlimContentPage?.DirectoryPropertiesViewModel is not null) SidebarAdaptiveViewModel.PaneHolder.ActivePaneOrColumn.SlimContentPage.DirectoryPropertiesViewModel.ShowLocals = true;