From 340239031be171dac2d329ab7cd1854efc107c92 Mon Sep 17 00:00:00 2001 From: jbe2277 Date: Sat, 25 Nov 2023 13:05:18 +0100 Subject: [PATCH] Simplify code by using new C# features --- .../Controllers/ManagerController.cs | 18 ++++----- .../Controllers/ModuleController.cs | 2 +- .../Controllers/MusicPropertiesController.cs | 10 ++--- .../Controllers/PlayerController.cs | 36 ++++++----------- .../Controllers/PlaylistController.cs | 23 +++++------ .../Controllers/TranscodingController.cs | 40 ++++++++----------- .../DataModels/FolderBrowserDataModel.cs | 6 ++- .../DataModels/FolderItem.cs | 14 ------- .../DataModels/MusicFileDataModel.cs | 8 ++-- .../DataModels/SearchFilterDataModel.cs | 4 +- .../Properties/PlaylistSettings.cs | 8 ++-- .../Services/ApplicationBusyContext.cs | 9 +---- .../Services/ChangeTrackerService.cs | 7 +--- .../Services/IFileService.cs | 8 ++-- .../Services/ISelectionService.cs | 2 +- .../Services/MusicTitleHelper.cs | 2 +- .../Services/SelectionService.cs | 8 +--- .../Services/ShellService.cs | 4 +- .../Services/TranscodingService.cs | 2 +- .../Services/TranscodingTaskEventArgs.cs | 12 ++---- .../ViewModels/ManagerViewModel.cs | 4 +- .../ViewModels/MusicPropertiesViewModel.cs | 14 ++++--- .../ViewModels/PlaylistViewModel.cs | 4 +- .../ViewModels/ShellViewModel.cs | 8 ++-- .../ViewModels/TranscodingListViewModel.cs | 4 +- .../MusicManager.Domain/MusicFiles/Entity.cs | 4 +- .../MusicManager.Domain/MusicFiles/Genres.cs | 5 +-- .../MusicFiles/MusicFile.cs | 4 +- .../MusicFiles/MusicMetadata.cs | 8 ++-- .../Playlists/PlayedItemsStack.cs | 2 +- .../Playlists/PlaylistItem.cs | 9 +---- .../Playlists/PlaylistManager.cs | 6 +-- .../Transcoding/TranscodingManager.cs | 4 +- .../Controls/Flyout.cs | 4 +- .../Controls/ListBoxDragDropHelper.cs | 6 +-- .../Controls/PathLabel.cs | 3 +- .../Controls/Rating.cs | 4 +- .../Controls/SearchableTextBlock.cs | 2 +- .../Controls/SelectionBehavior.cs | 38 +++++------------- .../DesignData/MockSelectionService.cs | 8 ++-- .../DesignData/SampleInfoViewModel.cs | 4 +- .../ListSortComparer.cs | 11 +---- .../Services/EnvironmentService.cs | 2 +- .../Services/FileService.cs | 1 - .../Services/MusicFileContext.cs | 16 ++++---- .../Services/SequenceEqualityComparer.cs | 2 +- .../Services/StringListConverter.cs | 2 +- .../Services/SupportedFileTypes.cs | 2 +- .../Views/ManagerView.xaml.cs | 9 ++--- .../Views/PlayerView.xaml.cs | 14 +++---- .../Views/PlaylistView.xaml.cs | 4 +- .../Views/ShellWindow.xaml.cs | 2 +- .../Views/TranscodingListView.xaml.cs | 16 +++----- 53 files changed, 171 insertions(+), 278 deletions(-) delete mode 100644 src/MusicManager/MusicManager.Applications/DataModels/FolderItem.cs diff --git a/src/MusicManager/MusicManager.Applications/Controllers/ManagerController.cs b/src/MusicManager/MusicManager.Applications/Controllers/ManagerController.cs index 3d43a7b..f076062 100644 --- a/src/MusicManager/MusicManager.Applications/Controllers/ManagerController.cs +++ b/src/MusicManager/MusicManager.Applications/Controllers/ManagerController.cs @@ -44,15 +44,15 @@ public ManagerController(IShellService shellService, IEnvironmentService environ this.managerStatusService = managerStatusService; this.fileSystemWatcherService = fileSystemWatcherService; this.managerViewModel = managerViewModel; - musicFiles = new ObservableCollection(); - updateSubDirectoriesCommand = new DelegateCommand(UpdateSubDirectories); - navigateDirectoryUpCommand = new DelegateCommand(NavigateDirectoryUp, CanNavigateDirectoryUp); - navigateHomeCommand = new DelegateCommand(NavigateHome); - navigatePublicHomeCommand = new DelegateCommand(NavigatePublicHome); - loadRecursiveCommand = new DelegateCommand(LoadRecursive); - navigateToSelectedSubDirectoryCommand = new DelegateCommand(NavigateToSelectedSubDirectory); - showMusicPropertiesCommand = new DelegateCommand(ShowMusicProperties); - deleteSelectedFilesCommand = new DelegateCommand(DeleteSelectedFiles); + musicFiles = []; + updateSubDirectoriesCommand = new(UpdateSubDirectories); + navigateDirectoryUpCommand = new(NavigateDirectoryUp, CanNavigateDirectoryUp); + navigateHomeCommand = new(NavigateHome); + navigatePublicHomeCommand = new(NavigatePublicHome); + loadRecursiveCommand = new(LoadRecursive); + navigateToSelectedSubDirectoryCommand = new(NavigateToSelectedSubDirectory); + showMusicPropertiesCommand = new(ShowMusicProperties); + deleteSelectedFilesCommand = new(DeleteSelectedFiles); } private ManagerViewModel ManagerViewModel => managerViewModel.Value; diff --git a/src/MusicManager/MusicManager.Applications/Controllers/ModuleController.cs b/src/MusicManager/MusicManager.Applications/Controllers/ModuleController.cs index b37168c..d1b328a 100644 --- a/src/MusicManager/MusicManager.Applications/Controllers/ModuleController.cs +++ b/src/MusicManager/MusicManager.Applications/Controllers/ModuleController.cs @@ -35,7 +35,7 @@ public ModuleController(Lazy shellService, ISettingsService settin this.playlistController = playlistController; this.transcodingController = transcodingController; this.shellViewModel = shellViewModel; - playlistManager = new PlaylistManager(); + playlistManager = new(); settingsService.ErrorOccurred += (sender, e) => Log.Default.Error(e.Error, "Error in SettingsService"); appSettings = settingsService.Get(); playlistSettings = settingsService.Get(); diff --git a/src/MusicManager/MusicManager.Applications/Controllers/MusicPropertiesController.cs b/src/MusicManager/MusicManager.Applications/Controllers/MusicPropertiesController.cs index 8726973..3095b96 100644 --- a/src/MusicManager/MusicManager.Applications/Controllers/MusicPropertiesController.cs +++ b/src/MusicManager/MusicManager.Applications/Controllers/MusicPropertiesController.cs @@ -25,8 +25,8 @@ public MusicPropertiesController(IShellService shellService, IMusicFileContext m this.musicFileContext = musicFileContext; this.selectionService = selectionService; this.musicPropertiesViewModel = musicPropertiesViewModel; - changeTrackerService = new ChangeTrackerService(); - musicFilesToSaveAfterPlaying = new HashSet(); + changeTrackerService = new(); + musicFilesToSaveAfterPlaying = []; } public PlaylistManager PlaylistManager { get; set; } = null!; @@ -49,7 +49,7 @@ public void Shutdown() if (musicFilesToSaveAfterPlaying.Any()) { - allFilesSavedCompletion = new TaskCompletionSource(); + allFilesSavedCompletion = new(); shellService.AddTaskToCompleteBeforeShutdown(allFilesSavedCompletion.Task); } } @@ -78,7 +78,7 @@ private async Task SaveDirtyFilesAsync() private async Task SaveMusicFilesToSaveAfterPlayingAsync() { - var tasks = musicFilesToSaveAfterPlaying.ToArray().Select(x => SaveChangesAsync(x)); + var tasks = musicFilesToSaveAfterPlaying.ToArray().Select(SaveChangesAsync); await Task.WhenAll(tasks); } @@ -98,7 +98,7 @@ private async Task SaveChangesAsync(MusicFile musicFile) } else { - allFilesToSave = new[] { musicFile }; + allFilesToSave = [ musicFile ]; } // Filter out the music file that is currently playing diff --git a/src/MusicManager/MusicManager.Applications/Controllers/PlayerController.cs b/src/MusicManager/MusicManager.Applications/Controllers/PlayerController.cs index 21d29d1..a448451 100644 --- a/src/MusicManager/MusicManager.Applications/Controllers/PlayerController.cs +++ b/src/MusicManager/MusicManager.Applications/Controllers/PlayerController.cs @@ -41,15 +41,15 @@ public PlayerController(IShellService shellService, IEnvironmentService environm this.playlistService = playlistService; this.playerViewModel = playerViewModel; this.infoViewModelFactory = infoViewModelFactory; - playAllCommand = new DelegateCommand(PlayAll, CanPlayAll); - playSelectedCommand = new DelegateCommand(PlaySelected, CanPlaySelected); - enqueueAllCommand = new DelegateCommand(EnqueueAll, CanEnqueueAll); - enqueueSelectedCommand = new DelegateCommand(EnqueueSelected, CanEnqueueSelected); - previousTrackCommand = new DelegateCommand(PreviousTrack, CanPreviousTrack); - nextTrackCommand = new DelegateCommand(NextTrack, CanNextTrack); - infoCommand = new DelegateCommand(ShowInfo); - showMusicPropertiesCommand = new DelegateCommand(ShowMusicProperties); - showPlaylistCommand = new DelegateCommand(ShowPlaylist); + playAllCommand = new(PlayAll, CanPlayAll); + playSelectedCommand = new(PlaySelected, CanPlaySelected); + enqueueAllCommand = new(EnqueueAll, CanEnqueueAll); + enqueueSelectedCommand = new(EnqueueSelected, CanEnqueueSelected); + previousTrackCommand = new(PreviousTrack, CanPreviousTrack); + nextTrackCommand = new(NextTrack, CanNextTrack); + infoCommand = new(ShowInfo); + showMusicPropertiesCommand = new(ShowMusicProperties); + showPlaylistCommand = new(ShowPlaylist); } public PlaylistManager PlaylistManager { get; set; } = null!; @@ -198,21 +198,9 @@ private void PlaylistManagerPropertyChanged(object? sender, PropertyChangedEvent } } - private void UpdateCommands() - { - previousTrackCommand.RaiseCanExecuteChanged(); - nextTrackCommand.RaiseCanExecuteChanged(); - } + private void UpdateCommands() => DelegateCommand.RaiseCanExecuteChanged(previousTrackCommand, nextTrackCommand); - private void MusicFilesCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) - { - playAllCommand.RaiseCanExecuteChanged(); - enqueueAllCommand.RaiseCanExecuteChanged(); - } + private void MusicFilesCollectionChanged(object? _, NotifyCollectionChangedEventArgs e) => DelegateCommand.RaiseCanExecuteChanged(playAllCommand, enqueueAllCommand); - private void SelectedMusicFilesCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) - { - playSelectedCommand.RaiseCanExecuteChanged(); - enqueueSelectedCommand.RaiseCanExecuteChanged(); - } + private void SelectedMusicFilesCollectionChanged(object? _, NotifyCollectionChangedEventArgs e) => DelegateCommand.RaiseCanExecuteChanged(playSelectedCommand, enqueueSelectedCommand); } diff --git a/src/MusicManager/MusicManager.Applications/Controllers/PlaylistController.cs b/src/MusicManager/MusicManager.Applications/Controllers/PlaylistController.cs index be46459..70d134b 100644 --- a/src/MusicManager/MusicManager.Applications/Controllers/PlaylistController.cs +++ b/src/MusicManager/MusicManager.Applications/Controllers/PlaylistController.cs @@ -5,7 +5,6 @@ using Waf.MusicManager.Applications.Properties; using Waf.MusicManager.Applications.Services; using Waf.MusicManager.Applications.ViewModels; -using Waf.MusicManager.Domain; using Waf.MusicManager.Domain.MusicFiles; using Waf.MusicManager.Domain.Playlists; @@ -43,14 +42,14 @@ public PlaylistController(IFileDialogService fileDialogService, IShellService sh this.musicFileContext = musicFileContext; this.playerService = playerService; this.musicPropertiesService = musicPropertiesService; - playSelectedCommand = new DelegateCommand(PlaySelected, CanPlaySelected); - removeSelectedCommand = new DelegateCommand(RemoveSelected, CanRemoveSelected); - showMusicPropertiesCommand = new DelegateCommand(ShowMusicProperties); - openListCommand = new DelegateCommand(OpenList); - saveListCommand = new DelegateCommand(SaveList); - clearListCommand = new DelegateCommand(ClearList); - openPlaylistFileType = new FileType(Resources.Playlist, IFileService.PlaylistFileExtensions); - savePlaylistFileType = new FileType(Resources.Playlist, IFileService.PlaylistFileExtensions[0]); + playSelectedCommand = new(PlaySelected, CanPlaySelected); + removeSelectedCommand = new(RemoveSelected, CanRemoveSelected); + showMusicPropertiesCommand = new(ShowMusicProperties); + openListCommand = new(OpenList); + saveListCommand = new(SaveList); + clearListCommand = new(ClearList); + openPlaylistFileType = new(Resources.Playlist, IFileService.PlaylistFileExtensions); + savePlaylistFileType = new(Resources.Playlist, IFileService.PlaylistFileExtensions[0]); } public PlaylistSettings PlaylistSettings { get; set; } = null!; @@ -214,9 +213,5 @@ private void PlaylistViewModelPropertyChanged(object? sender, PropertyChangedEve if (e.PropertyName == nameof(PlaylistViewModel.SelectedPlaylistItem)) UpdateCommands(); } - private void UpdateCommands() - { - playSelectedCommand.RaiseCanExecuteChanged(); - removeSelectedCommand.RaiseCanExecuteChanged(); - } + private void UpdateCommands() => DelegateCommand.RaiseCanExecuteChanged(playSelectedCommand, removeSelectedCommand); } diff --git a/src/MusicManager/MusicManager.Applications/Controllers/TranscodingController.cs b/src/MusicManager/MusicManager.Applications/Controllers/TranscodingController.cs index 4ec8fb3..b7f0f2e 100644 --- a/src/MusicManager/MusicManager.Applications/Controllers/TranscodingController.cs +++ b/src/MusicManager/MusicManager.Applications/Controllers/TranscodingController.cs @@ -41,14 +41,14 @@ public TranscodingController(IMessageService messageService, IShellService shell this.transcodingService = transcodingService; this.transcoder = transcoder; this.transcodingListViewModel = transcodingListViewModel; - cancellationTokenSources = new Dictionary(); - convertToMp3AllCommand = new DelegateCommand(ConvertToMp3All, CanConvertToMp3All); - convertToMp3SelectedCommand = new DelegateCommand(ConvertToMp3Selected, CanConvertToMp3Selected); - cancelAllCommand = new DelegateCommand(CancelAll, CanCancelAll); - cancelSelectedCommand = new DelegateCommand(CancelSelected, CanCancelSelected); - throttler = new SemaphoreSlim(Environment.ProcessorCount); // Do not dispose the throttler; it is used after Shutdown to cancel the open tasks - transcodingManager = new TranscodingManager(); - throttledMusicFilesCollectionChangedAction = new ThrottledAction(ThrottledMusicFilesCollectionChanged, ThrottledActionMode.InvokeOnlyIfIdleForDelayTime, TimeSpan.FromMilliseconds(10)); + cancellationTokenSources = []; + convertToMp3AllCommand = new(ConvertToMp3All, CanConvertToMp3All); + convertToMp3SelectedCommand = new(ConvertToMp3Selected, CanConvertToMp3Selected); + cancelAllCommand = new(CancelAll, CanCancelAll); + cancelSelectedCommand = new(CancelSelected, CanCancelSelected); + throttler = new(Environment.ProcessorCount); // Do not dispose the throttler; it is used after Shutdown to cancel the open tasks + transcodingManager = new(); + throttledMusicFilesCollectionChangedAction = new(ThrottledMusicFilesCollectionChanged, ThrottledActionMode.InvokeOnlyIfIdleForDelayTime, TimeSpan.FromMilliseconds(10)); } private TranscodingListViewModel TranscodingListViewModel => transcodingListViewModel.Value; @@ -60,7 +60,7 @@ public void Initialize() transcodingService.CancelAllCommand = cancelAllCommand; transcodingService.CancelSelectedCommand = cancelSelectedCommand; - shellService.TranscodingListView = new Lazy(InitializeTranscodingListView); + shellService.TranscodingListView = new(InitializeTranscodingListView); shellService.Closing += ShellServiceClosing; selectionService.MusicFiles.CollectionChanged += (sender, e) => throttledMusicFilesCollectionChangedAction.InvokeAccumulated(); @@ -71,7 +71,7 @@ public void Shutdown() { if (cancellationTokenSources.Any()) { - allTranscodingsCanceledCompletion = new TaskCompletionSource(); + allTranscodingsCanceledCompletion = new(); CancelAll(); shellService.AddTaskToCompleteBeforeShutdown(allTranscodingsCanceledCompletion.Task); } @@ -82,7 +82,7 @@ private object InitializeTranscodingListView() TranscodingListViewModel.TranscodingManager = transcodingManager; TranscodingListViewModel.InsertFilesAction = InsertFiles; TranscodingListViewModel.InsertMusicFilesAction = InsertMusicFiles; - CollectionChangedEventManager.AddHandler((INotifyCollectionChanged)TranscodingListViewModel.SelectedTranscodeItems, SelectedTranscodeItemsCollectionChanged); + CollectionChangedEventManager.AddHandler(TranscodingListViewModel.SelectedTranscodeItems, SelectedTranscodeItemsCollectionChanged); return TranscodingListViewModel.View; } @@ -179,9 +179,9 @@ private async void TranscodeAsync(MusicFile musicFile) finally { cancellationTokenSources.Remove(transcodeItem); - if (allTranscodingsCanceledCompletion != null && !cancellationTokenSources.Any()) + if (!cancellationTokenSources.Any()) { - allTranscodingsCanceledCompletion.SetResult(null); + allTranscodingsCanceledCompletion?.SetResult(null); } UpdateCancelCommands(); Log.Default.Trace("End Transcode: {0} > {1}", musicFile.FileName, destinationFileName); @@ -217,20 +217,12 @@ private async Task TranscodeAsyncCore(TranscodeItem transcodeItem, uint bitrate, <= 256000 => 256000, _ => 320000 }; - - private void ThrottledMusicFilesCollectionChanged() - { - convertToMp3AllCommand.RaiseCanExecuteChanged(); - convertToMp3SelectedCommand.RaiseCanExecuteChanged(); - } + + private void ThrottledMusicFilesCollectionChanged() => DelegateCommand.RaiseCanExecuteChanged(convertToMp3AllCommand, convertToMp3SelectedCommand); private void SelectedMusicFilesCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) => convertToMp3SelectedCommand.RaiseCanExecuteChanged(); private void SelectedTranscodeItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) => UpdateCancelCommands(); - private void UpdateCancelCommands() - { - cancelAllCommand.RaiseCanExecuteChanged(); - cancelSelectedCommand.RaiseCanExecuteChanged(); - } + private void UpdateCancelCommands() => DelegateCommand.RaiseCanExecuteChanged(cancelAllCommand, cancelSelectedCommand); } diff --git a/src/MusicManager/MusicManager.Applications/DataModels/FolderBrowserDataModel.cs b/src/MusicManager/MusicManager.Applications/DataModels/FolderBrowserDataModel.cs index 7491c94..f28dea6 100644 --- a/src/MusicManager/MusicManager.Applications/DataModels/FolderBrowserDataModel.cs +++ b/src/MusicManager/MusicManager.Applications/DataModels/FolderBrowserDataModel.cs @@ -1,10 +1,12 @@ -namespace Waf.MusicManager.Applications.DataModels; +using Waf.MusicManager.Applications.Services; + +namespace Waf.MusicManager.Applications.DataModels; public class FolderBrowserDataModel : Model { private string userPath = ""; private string currentPath = null!; - private IReadOnlyList subDirectories = Array.Empty(); + private IReadOnlyList subDirectories = []; private FolderItem? selectedSubDirectory; public string UserPath diff --git a/src/MusicManager/MusicManager.Applications/DataModels/FolderItem.cs b/src/MusicManager/MusicManager.Applications/DataModels/FolderItem.cs deleted file mode 100644 index d547e39..0000000 --- a/src/MusicManager/MusicManager.Applications/DataModels/FolderItem.cs +++ /dev/null @@ -1,14 +0,0 @@ -namespace Waf.MusicManager.Applications.DataModels; - -public class FolderItem -{ - public FolderItem(string? path, string displayName) - { - Path = path; - DisplayName = displayName; - } - - public string? Path { get; } - - public string DisplayName { get; } -} diff --git a/src/MusicManager/MusicManager.Applications/DataModels/MusicFileDataModel.cs b/src/MusicManager/MusicManager.Applications/DataModels/MusicFileDataModel.cs index 9fe85c9..9b40e63 100644 --- a/src/MusicManager/MusicManager.Applications/DataModels/MusicFileDataModel.cs +++ b/src/MusicManager/MusicManager.Applications/DataModels/MusicFileDataModel.cs @@ -5,6 +5,8 @@ namespace Waf.MusicManager.Applications.DataModels; public class MusicFileDataModel : Model { + private IWeakEventProxy? musicFilePropertyChangedProxy; + public MusicFileDataModel(MusicFile musicFile) { MusicFile = musicFile; @@ -14,13 +16,13 @@ public MusicFileDataModel(MusicFile musicFile) } else { - PropertyChangedEventManager.AddHandler(musicFile, MusicFilePropertyChanged, ""); + musicFilePropertyChangedProxy = WeakEvent.PropertyChanged.Add(musicFile, MusicFilePropertyChanged); } } public MusicFile MusicFile { get; } - public string ArtistsString => string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator + " ", MusicFile.IsMetadataLoaded ? MusicFile.Metadata.Artists : Array.Empty()); + public string ArtistsString => string.Join(CultureInfo.CurrentCulture.TextInfo.ListSeparator + " ", MusicFile.IsMetadataLoaded ? MusicFile.Metadata.Artists : []); private void MetadataLoaded() => PropertyChangedEventManager.AddHandler(MusicFile.Metadata, MetadataPropertyChanged, ""); @@ -28,7 +30,7 @@ private void MusicFilePropertyChanged(object? sender, PropertyChangedEventArgs e { if (e.PropertyName == nameof(MusicFile.IsMetadataLoaded)) { - PropertyChangedEventManager.RemoveHandler(MusicFile, MusicFilePropertyChanged, ""); + WeakEvent.TryRemove(ref musicFilePropertyChangedProxy); MetadataLoaded(); RaisePropertyChanged(nameof(ArtistsString)); } diff --git a/src/MusicManager/MusicManager.Applications/DataModels/SearchFilterDataModel.cs b/src/MusicManager/MusicManager.Applications/DataModels/SearchFilterDataModel.cs index 9cba2b2..81709f1 100644 --- a/src/MusicManager/MusicManager.Applications/DataModels/SearchFilterDataModel.cs +++ b/src/MusicManager/MusicManager.Applications/DataModels/SearchFilterDataModel.cs @@ -9,7 +9,7 @@ public class SearchFilterDataModel : Model private string artistFilter = ""; private string titleFilter = ""; private string albumFilter = ""; - private IReadOnlyList genreFilter = Array.Empty(); + private IReadOnlyList genreFilter = []; private FilterOperator ratingFilterOperator; private uint ratingFilter; private uint? fromYearFilter; @@ -144,7 +144,7 @@ public void Clear() ArtistFilter = ""; TitleFilter = ""; AlbumFilter = ""; - if (GenreFilter.Any()) GenreFilter = Array.Empty(); + if (GenreFilter.Any()) GenreFilter = []; FromYearFilter = ""; ToYearFilter = ""; RatingFilter = 0; diff --git a/src/MusicManager/MusicManager.Applications/Properties/PlaylistSettings.cs b/src/MusicManager/MusicManager.Applications/Properties/PlaylistSettings.cs index 47e7aa7..f3c0406 100644 --- a/src/MusicManager/MusicManager.Applications/Properties/PlaylistSettings.cs +++ b/src/MusicManager/MusicManager.Applications/Properties/PlaylistSettings.cs @@ -6,13 +6,13 @@ namespace Waf.MusicManager.Applications.Properties; [DataContract] public sealed class PlaylistSettings : UserSettingsBase { - [DataMember(Name = "FileNames")] private readonly List fileNames = new(); + [DataMember(Name = "FileNames")] private readonly List fileNames = []; [DataMember] public string? LastPlayedFileName { get; set; } [DataMember] public TimeSpan LastPlayedFilePosition { get; set; } - public IReadOnlyList FileNames { get { return fileNames; } } + public IReadOnlyList FileNames => fileNames; public void ReplaceAll(IEnumerable newFileNames) { @@ -20,7 +20,5 @@ public void ReplaceAll(IEnumerable newFileNames) fileNames.AddRange(newFileNames); } - protected override void SetDefaultValues() - { - } + protected override void SetDefaultValues() { } } diff --git a/src/MusicManager/MusicManager.Applications/Services/ApplicationBusyContext.cs b/src/MusicManager/MusicManager.Applications/Services/ApplicationBusyContext.cs index 83317c4..194caab 100644 --- a/src/MusicManager/MusicManager.Applications/Services/ApplicationBusyContext.cs +++ b/src/MusicManager/MusicManager.Applications/Services/ApplicationBusyContext.cs @@ -1,13 +1,6 @@ namespace Waf.MusicManager.Applications.Services; -internal class ApplicationBusyContext : IDisposable +internal sealed class ApplicationBusyContext(Action disposeCallback) : IDisposable { - private readonly Action disposeCallback; - - public ApplicationBusyContext(Action disposeCallback) - { - this.disposeCallback = disposeCallback; - } - public void Dispose() => disposeCallback(this); } diff --git a/src/MusicManager/MusicManager.Applications/Services/ChangeTrackerService.cs b/src/MusicManager/MusicManager.Applications/Services/ChangeTrackerService.cs index 28d8062..65afd34 100644 --- a/src/MusicManager/MusicManager.Applications/Services/ChangeTrackerService.cs +++ b/src/MusicManager/MusicManager.Applications/Services/ChangeTrackerService.cs @@ -4,12 +4,7 @@ namespace Waf.MusicManager.Applications.Services; internal class ChangeTrackerService : IChangeTrackerService { - private readonly HashSet entitiesWithChanges; - - public ChangeTrackerService() - { - entitiesWithChanges = new HashSet(); - } + private readonly HashSet entitiesWithChanges = []; public IEnumerable GetEntitiesWithChanges() => entitiesWithChanges.ToArray(); diff --git a/src/MusicManager/MusicManager.Applications/Services/IFileService.cs b/src/MusicManager/MusicManager.Applications/Services/IFileService.cs index d672c0f..5457391 100644 --- a/src/MusicManager/MusicManager.Applications/Services/IFileService.cs +++ b/src/MusicManager/MusicManager.Applications/Services/IFileService.cs @@ -1,10 +1,10 @@ -using Waf.MusicManager.Applications.DataModels; - -namespace Waf.MusicManager.Applications.Services +namespace Waf.MusicManager.Applications.Services { + public record FolderItem(string? Path, string DisplayName); + public interface IFileService { - static IReadOnlyList PlaylistFileExtensions { get; } = new string[] { ".m3u", ".wpl" }; + static IReadOnlyList PlaylistFileExtensions { get; } = [ ".m3u", ".wpl" ]; bool IsFileSupported(string fileName); diff --git a/src/MusicManager/MusicManager.Applications/Services/ISelectionService.cs b/src/MusicManager/MusicManager.Applications/Services/ISelectionService.cs index bf6412a..6c01131 100644 --- a/src/MusicManager/MusicManager.Applications/Services/ISelectionService.cs +++ b/src/MusicManager/MusicManager.Applications/Services/ISelectionService.cs @@ -7,5 +7,5 @@ public interface ISelectionService { ObservableListView MusicFiles { get; } - ObservableCollection SelectedMusicFiles { get; } + ObservableList SelectedMusicFiles { get; } } diff --git a/src/MusicManager/MusicManager.Applications/Services/MusicTitleHelper.cs b/src/MusicManager/MusicManager.Applications/Services/MusicTitleHelper.cs index 48178f3..800beae 100644 --- a/src/MusicManager/MusicManager.Applications/Services/MusicTitleHelper.cs +++ b/src/MusicManager/MusicManager.Applications/Services/MusicTitleHelper.cs @@ -6,7 +6,7 @@ public static class MusicTitleHelper { public static string GetTitleText(string? fileName, IEnumerable? artists, string? title) { - artists ??= Array.Empty(); + artists ??= []; var result = string.IsNullOrEmpty(title) && !artists.Any() ? Path.GetFileNameWithoutExtension(fileName) : title; return result ?? ""; } diff --git a/src/MusicManager/MusicManager.Applications/Services/SelectionService.cs b/src/MusicManager/MusicManager.Applications/Services/SelectionService.cs index 2d9d043..d5c9106 100644 --- a/src/MusicManager/MusicManager.Applications/Services/SelectionService.cs +++ b/src/MusicManager/MusicManager.Applications/Services/SelectionService.cs @@ -8,15 +8,9 @@ namespace Waf.MusicManager.Applications.Services; [Export, Export(typeof(ISelectionService))] internal class SelectionService : ISelectionService { - [ImportingConstructor] - public SelectionService() - { - SelectedMusicFiles = new ObservableCollection(); - } - public ObservableListView MusicFiles { get; private set; } = null!; - public ObservableCollection SelectedMusicFiles { get; } + public ObservableList SelectedMusicFiles { get; } = []; public void Initialize(IEnumerable musicFiles) { diff --git a/src/MusicManager/MusicManager.Applications/Services/ShellService.cs b/src/MusicManager/MusicManager.Applications/Services/ShellService.cs index 55e32ef..6f45089 100644 --- a/src/MusicManager/MusicManager.Applications/Services/ShellService.cs +++ b/src/MusicManager/MusicManager.Applications/Services/ShellService.cs @@ -23,8 +23,8 @@ internal class ShellService : Model, IShellService public ShellService(Lazy shellView) { this.shellView = shellView; - tasksToCompleteBeforeShutdown = new List(); - applicationBusyContext = new List(); + tasksToCompleteBeforeShutdown = []; + applicationBusyContext = []; } public AppSettings Settings { get; set; } = null!; diff --git a/src/MusicManager/MusicManager.Applications/Services/TranscodingService.cs b/src/MusicManager/MusicManager.Applications/Services/TranscodingService.cs index 071823d..4490e3e 100644 --- a/src/MusicManager/MusicManager.Applications/Services/TranscodingService.cs +++ b/src/MusicManager/MusicManager.Applications/Services/TranscodingService.cs @@ -38,7 +38,7 @@ public ICommand CancelSelectedCommand public event EventHandler? TranscodingTaskCreated; - public void RaiseTranscodingTaskCreated(string fileName, Task transcodingTask) => OnTranscodingTaskCreated(new TranscodingTaskEventArgs(fileName, transcodingTask)); + public void RaiseTranscodingTaskCreated(string fileName, Task transcodingTask) => OnTranscodingTaskCreated(new(fileName, transcodingTask)); protected virtual void OnTranscodingTaskCreated(TranscodingTaskEventArgs e) => TranscodingTaskCreated?.Invoke(this, e); } diff --git a/src/MusicManager/MusicManager.Applications/Services/TranscodingTaskEventArgs.cs b/src/MusicManager/MusicManager.Applications/Services/TranscodingTaskEventArgs.cs index db8dc6d..b26f771 100644 --- a/src/MusicManager/MusicManager.Applications/Services/TranscodingTaskEventArgs.cs +++ b/src/MusicManager/MusicManager.Applications/Services/TranscodingTaskEventArgs.cs @@ -1,14 +1,8 @@ namespace Waf.MusicManager.Applications.Services; -public class TranscodingTaskEventArgs : EventArgs +public class TranscodingTaskEventArgs(string fileName, Task transcodingTask) : EventArgs { - public TranscodingTaskEventArgs(string fileName, Task transcodingTask) - { - FileName = fileName; - TranscodingTask = transcodingTask; - } + public string FileName { get; } = fileName; - public string FileName { get; } - - public Task TranscodingTask { get; } + public Task TranscodingTask { get; } = transcodingTask; } diff --git a/src/MusicManager/MusicManager.Applications/ViewModels/ManagerViewModel.cs b/src/MusicManager/MusicManager.Applications/ViewModels/ManagerViewModel.cs index 1e7a279..8ff02b5 100644 --- a/src/MusicManager/MusicManager.Applications/ViewModels/ManagerViewModel.cs +++ b/src/MusicManager/MusicManager.Applications/ViewModels/ManagerViewModel.cs @@ -29,8 +29,8 @@ public ManagerViewModel(IManagerView view, Lazy selectionServ ManagerStatusService = managerStatusService; PlayerService = playerService; TranscodingService = transcodingService; - FolderBrowser = new FolderBrowserDataModel(); - SearchFilter = new SearchFilterDataModel(); + FolderBrowser = new(); + SearchFilter = new(); ClearSearchCommand = new DelegateCommand(ClearSearch); } diff --git a/src/MusicManager/MusicManager.Applications/ViewModels/MusicPropertiesViewModel.cs b/src/MusicManager/MusicManager.Applications/ViewModels/MusicPropertiesViewModel.cs index 3cb2d13..2e575f4 100644 --- a/src/MusicManager/MusicManager.Applications/ViewModels/MusicPropertiesViewModel.cs +++ b/src/MusicManager/MusicManager.Applications/ViewModels/MusicPropertiesViewModel.cs @@ -14,13 +14,15 @@ public class MusicPropertiesViewModel : ViewModel private readonly IClipboardService clipboardService; private readonly DelegateCommand autoFillFromFileNameCommand; private MusicFile? musicFile; + private IWeakEventProxy? musicFilePropertyChangedProxy; + private IWeakEventProxy? metadataPropertyChangedProxy; [ImportingConstructor] public MusicPropertiesViewModel(IMusicPropertiesView view, IClipboardService clipboardService) : base(view) { this.clipboardService = clipboardService; CopyFileNameCommand = new DelegateCommand(CopyFileNameToClipboard); - autoFillFromFileNameCommand = new DelegateCommand(AutoFillFromFileName, CanAutoFillFromFileName); + autoFillFromFileNameCommand = new(AutoFillFromFileName, CanAutoFillFromFileName); } public ICommand CopyFileNameCommand { get; } @@ -35,13 +37,13 @@ public MusicFile? MusicFile if (musicFile == value) return; if (musicFile != null) { - PropertyChangedEventManager.RemoveHandler(musicFile, MusicFilePropertyChanged, ""); - if (musicFile.IsMetadataLoaded) PropertyChangedEventManager.RemoveHandler(musicFile.Metadata, MetadataPropertyChanged, ""); + WeakEvent.TryRemove(ref musicFilePropertyChangedProxy); + if (musicFile.IsMetadataLoaded) WeakEvent.TryRemove(ref metadataPropertyChangedProxy); } musicFile = value; if (musicFile != null) { - PropertyChangedEventManager.AddHandler(musicFile, MusicFilePropertyChanged, ""); + musicFilePropertyChangedProxy = WeakEvent.PropertyChanged.Add(musicFile, MusicFilePropertyChanged); MetadataLoaded(); } RaisePropertyChanged(); @@ -65,7 +67,7 @@ private void AutoFillFromFileName() var metadata = fileName.Split(['-'], 2).Select(x => x.Trim()).ToArray(); if (metadata.Length == 2) { - MusicFile!.Metadata!.Artists = new[] { metadata[0] }; + MusicFile!.Metadata!.Artists = [ metadata[0] ]; MusicFile.Metadata.Title = metadata[1]; } else @@ -77,7 +79,7 @@ private void AutoFillFromFileName() private void MetadataLoaded() { if (MusicFile?.IsMetadataLoaded != true) return; - PropertyChangedEventManager.AddHandler(MusicFile.Metadata, MetadataPropertyChanged, ""); + metadataPropertyChangedProxy = WeakEvent.PropertyChanged.Add(MusicFile.Metadata, MetadataPropertyChanged); autoFillFromFileNameCommand.RaiseCanExecuteChanged(); } diff --git a/src/MusicManager/MusicManager.Applications/ViewModels/PlaylistViewModel.cs b/src/MusicManager/MusicManager.Applications/ViewModels/PlaylistViewModel.cs index 3f987a6..9fb5432 100644 --- a/src/MusicManager/MusicManager.Applications/ViewModels/PlaylistViewModel.cs +++ b/src/MusicManager/MusicManager.Applications/ViewModels/PlaylistViewModel.cs @@ -24,7 +24,7 @@ public class PlaylistViewModel : ViewModel [ImportingConstructor] public PlaylistViewModel(IPlaylistView view) : base(view) { - SelectedPlaylistItems = new ObservableCollection(); + SelectedPlaylistItems = []; SearchNextCommand = new DelegateCommand(SearchNext); SearchPreviousCommand = new DelegateCommand(SearchPrevious); ClearSearchCommand = new DelegateCommand(ClearSearch); @@ -42,7 +42,7 @@ public PlaylistItem? SelectedPlaylistItem set => SetProperty(ref selectedPlaylistItem, value); } - public IList SelectedPlaylistItems { get; } + public ObservableList SelectedPlaylistItems { get; } public ICommand PlaySelectedCommand { diff --git a/src/MusicManager/MusicManager.Applications/ViewModels/ShellViewModel.cs b/src/MusicManager/MusicManager.Applications/ViewModels/ShellViewModel.cs index 295621b..0de8dd0 100644 --- a/src/MusicManager/MusicManager.Applications/ViewModels/ShellViewModel.cs +++ b/src/MusicManager/MusicManager.Applications/ViewModels/ShellViewModel.cs @@ -11,7 +11,7 @@ namespace Waf.MusicManager.Applications.ViewModels; public class ShellViewModel : ViewModel { private readonly AppSettings settings; - private readonly ObservableCollection> errors; + private readonly ObservableList> errors; private object? detailsView; [ImportingConstructor] @@ -20,7 +20,7 @@ public ShellViewModel(IShellView view, IShellService shellService, IPlayerServic ShellService = shellService; PlayerService = playerService; settings = shellService.Settings; - errors = new ObservableCollection>(); + errors = []; ExitCommand = new DelegateCommand(Close); CloseErrorCommand = new DelegateCommand(CloseError); GarbageCollectorCommand = new DelegateCommand(GC.Collect); @@ -91,9 +91,7 @@ protected override void OnPropertyChanged(PropertyChangedEventArgs e) base.OnPropertyChanged(e); if (e.PropertyName == nameof(DetailsView)) { - RaisePropertyChanged(nameof(IsMusicPropertiesViewVisible)); - RaisePropertyChanged(nameof(IsPlaylistViewVisible)); - RaisePropertyChanged(nameof(IsTranscodingListViewVisible)); + RaisePropertyChanged(nameof(IsMusicPropertiesViewVisible), nameof(IsPlaylistViewVisible), nameof(IsTranscodingListViewVisible)); } } diff --git a/src/MusicManager/MusicManager.Applications/ViewModels/TranscodingListViewModel.cs b/src/MusicManager/MusicManager.Applications/ViewModels/TranscodingListViewModel.cs index e3b5ed4..2057cbf 100644 --- a/src/MusicManager/MusicManager.Applications/ViewModels/TranscodingListViewModel.cs +++ b/src/MusicManager/MusicManager.Applications/ViewModels/TranscodingListViewModel.cs @@ -16,12 +16,12 @@ public class TranscodingListViewModel : ViewModel public TranscodingListViewModel(ITranscodingListView view, ITranscodingService transcodingService) : base(view) { TranscodingService = transcodingService; - SelectedTranscodeItems = new ObservableCollection(); + SelectedTranscodeItems = []; } public ITranscodingService TranscodingService { get; } - public IList SelectedTranscodeItems { get; } + public ObservableList SelectedTranscodeItems { get; } public TranscodingManager TranscodingManager { diff --git a/src/MusicManager/MusicManager.Domain/MusicFiles/Entity.cs b/src/MusicManager/MusicManager.Domain/MusicFiles/Entity.cs index 35ebf71..ad7b2b9 100644 --- a/src/MusicManager/MusicManager.Domain/MusicFiles/Entity.cs +++ b/src/MusicManager/MusicManager.Domain/MusicFiles/Entity.cs @@ -11,8 +11,8 @@ public abstract class Entity : Model protected Entity() { - changeTrackerService = new Lazy(ServiceLocator.Get); - changes = new HashSet(); + changeTrackerService = new(ServiceLocator.Get); + changes = []; } public bool HasChanges diff --git a/src/MusicManager/MusicManager.Domain/MusicFiles/Genres.cs b/src/MusicManager/MusicManager.Domain/MusicFiles/Genres.cs index 1568dfe..f8efea1 100644 --- a/src/MusicManager/MusicManager.Domain/MusicFiles/Genres.cs +++ b/src/MusicManager/MusicManager.Domain/MusicFiles/Genres.cs @@ -2,8 +2,7 @@ public static class Genres { - public static IReadOnlyList DefaultValues { get; } = new[] - { + public static IReadOnlyList DefaultValues { get; } = [ "Blues", "Classical", "Comedy", @@ -21,5 +20,5 @@ public static class Genres "Rock", "Soundtrack", "Techno" - }; + ]; } diff --git a/src/MusicManager/MusicManager.Domain/MusicFiles/MusicFile.cs b/src/MusicManager/MusicManager.Domain/MusicFiles/MusicFile.cs index 5c4d6a2..fbe06ae 100644 --- a/src/MusicManager/MusicManager.Domain/MusicFiles/MusicFile.cs +++ b/src/MusicManager/MusicManager.Domain/MusicFiles/MusicFile.cs @@ -12,10 +12,10 @@ public class MusicFile : Model public MusicFile(Func> loadMetadata, string? fileName) { - loadMetadataCompletionSource = new TaskCompletionSource(); + loadMetadataCompletionSource = new(); this.loadMetadata = loadMetadata; FileName = fileName; - sharedMusicFiles = Array.Empty(); + sharedMusicFiles = []; } public string? FileName { get; } diff --git a/src/MusicManager/MusicManager.Domain/MusicFiles/MusicMetadata.cs b/src/MusicManager/MusicManager.Domain/MusicFiles/MusicMetadata.cs index 7e8be29..a59eb2b 100644 --- a/src/MusicManager/MusicManager.Domain/MusicFiles/MusicMetadata.cs +++ b/src/MusicManager/MusicManager.Domain/MusicFiles/MusicMetadata.cs @@ -2,18 +2,18 @@ public class MusicMetadata : Entity { - private IReadOnlyList artists = Array.Empty(); + private IReadOnlyList artists = []; private string title = ""; private uint rating; private string album = ""; private uint trackNumber; private uint year; - private IReadOnlyList genre = Array.Empty(); + private IReadOnlyList genre = []; private string albumArtist = ""; private string publisher = ""; private string subtitle = ""; - private IReadOnlyList composers = Array.Empty(); - private IReadOnlyList conductors = Array.Empty(); + private IReadOnlyList composers = []; + private IReadOnlyList conductors = []; private MusicMetadata(TimeSpan duration, long bitrate, bool isSupported) { diff --git a/src/MusicManager/MusicManager.Domain/Playlists/PlayedItemsStack.cs b/src/MusicManager/MusicManager.Domain/Playlists/PlayedItemsStack.cs index aaff414..bf81043 100644 --- a/src/MusicManager/MusicManager.Domain/Playlists/PlayedItemsStack.cs +++ b/src/MusicManager/MusicManager.Domain/Playlists/PlayedItemsStack.cs @@ -8,7 +8,7 @@ internal class PlayedItemsStack public PlayedItemsStack(int capacity) { this.capacity = capacity; - playlistItems = new LinkedList(); + playlistItems = []; } public int Count => playlistItems.Count; diff --git a/src/MusicManager/MusicManager.Domain/Playlists/PlaylistItem.cs b/src/MusicManager/MusicManager.Domain/Playlists/PlaylistItem.cs index df86a70..204a994 100644 --- a/src/MusicManager/MusicManager.Domain/Playlists/PlaylistItem.cs +++ b/src/MusicManager/MusicManager.Domain/Playlists/PlaylistItem.cs @@ -2,12 +2,7 @@ namespace Waf.MusicManager.Domain.Playlists; -public class PlaylistItem : Model +public class PlaylistItem(MusicFile musicFile) : Model { - public PlaylistItem(MusicFile musicFile) - { - MusicFile = musicFile; - } - - public MusicFile MusicFile { get; } + public MusicFile MusicFile { get; } = musicFile; } diff --git a/src/MusicManager/MusicManager.Domain/Playlists/PlaylistManager.cs b/src/MusicManager/MusicManager.Domain/Playlists/PlaylistManager.cs index 67984de..69eabc2 100644 --- a/src/MusicManager/MusicManager.Domain/Playlists/PlaylistManager.cs +++ b/src/MusicManager/MusicManager.Domain/Playlists/PlaylistManager.cs @@ -5,7 +5,7 @@ namespace Waf.MusicManager.Domain.Playlists; public class PlaylistManager : Model { private readonly IRandomService randomService; - private readonly ObservableCollection items; + private readonly ObservableList items; private readonly PlayedItemsStack playedItemsStack; private bool isTotalDurationEstimated; private TimeSpan totalDuration; @@ -18,9 +18,9 @@ public class PlaylistManager : Model public PlaylistManager(int playedItemStackCapacity = 1000, IRandomService? randomService = null) { this.randomService = randomService ?? new RandomService(); - items = new ObservableCollection(); + items = []; Items = new ReadOnlyObservableList(items); - playedItemsStack = new PlayedItemsStack(playedItemStackCapacity); + playedItemsStack = new(playedItemStackCapacity); items.CollectionChanged += ItemsCollectionChanged; } diff --git a/src/MusicManager/MusicManager.Domain/Transcoding/TranscodingManager.cs b/src/MusicManager/MusicManager.Domain/Transcoding/TranscodingManager.cs index b607c20..2cda28b 100644 --- a/src/MusicManager/MusicManager.Domain/Transcoding/TranscodingManager.cs +++ b/src/MusicManager/MusicManager.Domain/Transcoding/TranscodingManager.cs @@ -2,11 +2,11 @@ public class TranscodingManager { - private readonly ObservableCollection transcodeItems; + private readonly ObservableList transcodeItems; public TranscodingManager() { - transcodeItems = new ObservableCollection(); + transcodeItems = []; TranscodeItems = new ReadOnlyObservableList(transcodeItems); } diff --git a/src/MusicManager/MusicManager.Presentation/Controls/Flyout.cs b/src/MusicManager/MusicManager.Presentation/Controls/Flyout.cs index 5412556..2950157 100644 --- a/src/MusicManager/MusicManager.Presentation/Controls/Flyout.cs +++ b/src/MusicManager/MusicManager.Presentation/Controls/Flyout.cs @@ -8,10 +8,10 @@ namespace Waf.MusicManager.Presentation.Controls; public class Flyout : Popup { public static readonly DependencyProperty HorizontalFlyoutAlignmentProperty = - DependencyProperty.Register(nameof(HorizontalFlyoutAlignment), typeof(HorizontalFlyoutAlignment), typeof(Flyout), new PropertyMetadata(HorizontalFlyoutAlignment.Left)); + DependencyProperty.Register(nameof(HorizontalFlyoutAlignment), typeof(HorizontalFlyoutAlignment), typeof(Flyout), new(HorizontalFlyoutAlignment.Left)); public new static readonly DependencyProperty HorizontalOffsetProperty = - DependencyProperty.Register(nameof(HorizontalOffset), typeof(double), typeof(Flyout), new PropertyMetadata(0d)); + DependencyProperty.Register(nameof(HorizontalOffset), typeof(double), typeof(Flyout), new(0d)); private readonly Stopwatch closedStopwatch; diff --git a/src/MusicManager/MusicManager.Presentation/Controls/ListBoxDragDropHelper.cs b/src/MusicManager/MusicManager.Presentation/Controls/ListBoxDragDropHelper.cs index 4473e95..212d611 100644 --- a/src/MusicManager/MusicManager.Presentation/Controls/ListBoxDragDropHelper.cs +++ b/src/MusicManager/MusicManager.Presentation/Controls/ListBoxDragDropHelper.cs @@ -26,8 +26,8 @@ public ListBoxDragDropHelper(ListBox listBox, Action>? m this.moveItemsAction = moveItemsAction; this.tryGetInsertItemsAction = tryGetInsertItemsAction ?? (eventArgs => null); this.insertItemsAction = insertItemsAction; - insertMarkerAdorner = new InsertMarkerAdorner(listBox); - throttledAutoScrollAction = new ThrottledAction(ThrottledAutoScroll, ThrottledActionMode.InvokeMaxEveryDelayTime, TimeSpan.FromMilliseconds(250)); + insertMarkerAdorner = new(listBox); + throttledAutoScrollAction = new(ThrottledAutoScroll, ThrottledActionMode.InvokeMaxEveryDelayTime, TimeSpan.FromMilliseconds(250)); listBox.Loaded += ListBoxLoaded; if (listBox.IsLoaded) InitializeAdornerLayer(); @@ -59,7 +59,7 @@ private void ListBoxItemPreviewMouseMove(object sender, MouseEventArgs e) var target = (ListBoxItem)sender; var items = listBox.Items.Cast().ToList(); - var selectedItems = listBox.SelectedItems.Cast().OrderBy(x => items.IndexOf(x)).ToArray(); + var selectedItems = listBox.SelectedItems.Cast().OrderBy(items.IndexOf).ToArray(); dragSource = target; DragDrop.DoDragDrop(target, selectedItems, DragDropEffects.Move); diff --git a/src/MusicManager/MusicManager.Presentation/Controls/PathLabel.cs b/src/MusicManager/MusicManager.Presentation/Controls/PathLabel.cs index d6e257a..20e6c54 100644 --- a/src/MusicManager/MusicManager.Presentation/Controls/PathLabel.cs +++ b/src/MusicManager/MusicManager.Presentation/Controls/PathLabel.cs @@ -16,8 +16,7 @@ public class PathLabel : Label public PathLabel() { - textBlock = new TextBlock(); - + textBlock = new(); Loaded += LoadedHandler; SizeChanged += SizeChangedHandler; } diff --git a/src/MusicManager/MusicManager.Presentation/Controls/Rating.cs b/src/MusicManager/MusicManager.Presentation/Controls/Rating.cs index ef8bccd..31edd3c 100644 --- a/src/MusicManager/MusicManager.Presentation/Controls/Rating.cs +++ b/src/MusicManager/MusicManager.Presentation/Controls/Rating.cs @@ -22,7 +22,7 @@ static Rating() public Rating() { - ratingItems = new ReadOnlyCollection(Array.Empty()); + ratingItems = new([]); } public override void OnApplyTemplate() @@ -72,7 +72,7 @@ private void GenerateRatingItems() item.Click += ItemClick; items.Add(item); } - ratingItems = new ReadOnlyCollection(items); + ratingItems = new(items); itemsControl.ItemsSource = ratingItems; } } diff --git a/src/MusicManager/MusicManager.Presentation/Controls/SearchableTextBlock.cs b/src/MusicManager/MusicManager.Presentation/Controls/SearchableTextBlock.cs index 937b6fe..3220a82 100644 --- a/src/MusicManager/MusicManager.Presentation/Controls/SearchableTextBlock.cs +++ b/src/MusicManager/MusicManager.Presentation/Controls/SearchableTextBlock.cs @@ -19,7 +19,7 @@ public class SearchableTextBlock : TextBlock public static readonly DependencyProperty IsMatchCaseProperty = DependencyProperty.Register(nameof(IsMatchCase), typeof(bool), typeof(SearchableTextBlock), new FrameworkPropertyMetadata(false, ControlPropertyChangedCallback)); - private IReadOnlyList textParts = Array.Empty(); + private IReadOnlyList textParts = []; public new string Text { diff --git a/src/MusicManager/MusicManager.Presentation/Controls/SelectionBehavior.cs b/src/MusicManager/MusicManager.Presentation/Controls/SelectionBehavior.cs index c7e9760..0ea8e52 100644 --- a/src/MusicManager/MusicManager.Presentation/Controls/SelectionBehavior.cs +++ b/src/MusicManager/MusicManager.Presentation/Controls/SelectionBehavior.cs @@ -7,9 +7,9 @@ namespace Waf.MusicManager.Presentation.Controls; public static class SelectionBehavior { - private static readonly List> multiSelectorWithObservableList = new(); - private static readonly HashSet syncListsThatAreUpdating = new(); - private static readonly HashSet selectorsThatAreUpdating = new(); + private static readonly List<(IMultiSelector selector, INotifyCollectionChanged observable)> multiSelectorWithObservableList = []; + private static readonly HashSet syncListsThatAreUpdating = []; + private static readonly HashSet selectorsThatAreUpdating = []; public static readonly DependencyProperty SyncSelectedItemsProperty = DependencyProperty.RegisterAttached("SyncSelectedItems", typeof(IList), typeof(SelectionBehavior), new FrameworkPropertyMetadata(null, SyncSelectedItemsPropertyChanged)); @@ -36,8 +36,8 @@ private static void SyncSelectedItemsPropertyChanged(DependencyObject element, D if (list is not INotifyCollectionChanged observableList) return; - multiSelectorWithObservableList.Add(Tuple.Create(multiSelector, observableList)); - CollectionChangedEventManager.AddHandler(observableList, ListCollectionChanged); + multiSelectorWithObservableList.Add((multiSelector, observableList)); + WeakEvent.CollectionChanged.Add(observableList, ListCollectionChanged); } finally { @@ -48,20 +48,14 @@ private static void SyncSelectedItemsPropertyChanged(DependencyObject element, D private static void TryCleanUpOldItem(Selector selector) { selector.SelectionChanged -= SelectorSelectionChanged; // Remove a previously added event handler. - - var item = multiSelectorWithObservableList.FirstOrDefault(x => x.Item1.Selector == selector); - if (item == null) return; - - multiSelectorWithObservableList.Remove(item); - CollectionChangedEventManager.RemoveHandler(item.Item2, ListCollectionChanged); + multiSelectorWithObservableList.RemoveAll(x => x.selector.Selector == selector); } - private static void ListCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { if (syncListsThatAreUpdating.Contains(sender!)) return; - var multiSelector = multiSelectorWithObservableList.First(x => x.Item2 == sender).Item1; + var multiSelector = multiSelectorWithObservableList.First(x => x.observable == sender).selector; selectorsThatAreUpdating.Add(multiSelector.Selector); try { @@ -121,29 +115,15 @@ private interface IMultiSelector IList SelectedItems { get; } } - private class ListBoxAdapter : IMultiSelector + private sealed class ListBoxAdapter(ListBox listBox) : IMultiSelector { - private readonly ListBox listBox; - - public ListBoxAdapter(ListBox listBox) - { - this.listBox = listBox; - } - public Selector Selector => listBox; public IList SelectedItems => listBox.SelectedItems; } - private class MultiSelectorAdapter : IMultiSelector + private sealed class MultiSelectorAdapter(MultiSelector multiSelector) : IMultiSelector { - private readonly MultiSelector multiSelector; - - public MultiSelectorAdapter(MultiSelector multiSelector) - { - this.multiSelector = multiSelector; - } - public Selector Selector => multiSelector; public IList SelectedItems => multiSelector.SelectedItems; diff --git a/src/MusicManager/MusicManager.Presentation/DesignData/MockSelectionService.cs b/src/MusicManager/MusicManager.Presentation/DesignData/MockSelectionService.cs index 8f70004..f39e541 100644 --- a/src/MusicManager/MusicManager.Presentation/DesignData/MockSelectionService.cs +++ b/src/MusicManager/MusicManager.Presentation/DesignData/MockSelectionService.cs @@ -10,14 +10,14 @@ public class MockSelectionService : ISelectionService public MockSelectionService() { - innerMusicFiles = new ObservableCollection(); - SelectedMusicFiles = new ObservableCollection(); - MusicFiles = new ObservableListView(innerMusicFiles); + innerMusicFiles = []; + SelectedMusicFiles = []; + MusicFiles = new(innerMusicFiles); } public ObservableListView MusicFiles { get; } - public ObservableCollection SelectedMusicFiles { get; } + public ObservableList SelectedMusicFiles { get; } public void SetMusicFiles(IEnumerable musicFiles) { diff --git a/src/MusicManager/MusicManager.Presentation/DesignData/SampleInfoViewModel.cs b/src/MusicManager/MusicManager.Presentation/DesignData/SampleInfoViewModel.cs index 47bd623..e14920c 100644 --- a/src/MusicManager/MusicManager.Presentation/DesignData/SampleInfoViewModel.cs +++ b/src/MusicManager/MusicManager.Presentation/DesignData/SampleInfoViewModel.cs @@ -11,8 +11,6 @@ public SampleInfoViewModel() : base(new MockInfoView()) private class MockInfoView : MockView, IInfoView { - public void ShowDialog(object owner) - { - } + public void ShowDialog(object owner) { } } } diff --git a/src/MusicManager/MusicManager.Presentation/ListSortComparer.cs b/src/MusicManager/MusicManager.Presentation/ListSortComparer.cs index 78faa0a..8d27b75 100644 --- a/src/MusicManager/MusicManager.Presentation/ListSortComparer.cs +++ b/src/MusicManager/MusicManager.Presentation/ListSortComparer.cs @@ -1,15 +1,6 @@ namespace Waf.MusicManager.Presentation; -public class ListSortComparer : IComparer +public class ListSortComparer(Comparison comparison, ListSortDirection sortDirection) : IComparer { - private readonly Comparison comparison; - private readonly ListSortDirection sortDirection; - - public ListSortComparer(Comparison comparison, ListSortDirection sortDirection) - { - this.comparison = comparison; - this.sortDirection = sortDirection; - } - public int Compare(T? x, T? y) => sortDirection == ListSortDirection.Ascending ? comparison(x, y) : comparison(y, x); } diff --git a/src/MusicManager/MusicManager.Presentation/Services/EnvironmentService.cs b/src/MusicManager/MusicManager.Presentation/Services/EnvironmentService.cs index 34cf673..e54ce8d 100644 --- a/src/MusicManager/MusicManager.Presentation/Services/EnvironmentService.cs +++ b/src/MusicManager/MusicManager.Presentation/Services/EnvironmentService.cs @@ -15,7 +15,7 @@ internal class EnvironmentService : IEnvironmentService public EnvironmentService() { - musicFilesToLoad = new Lazy>(() => Environment.GetCommandLineArgs().Skip(1).ToArray()); + musicFilesToLoad = new(() => Environment.GetCommandLineArgs().Skip(1).ToArray()); MusicPath = Environment.GetFolderPath(Environment.SpecialFolder.MyMusic); PublicMusicPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonMusic); } diff --git a/src/MusicManager/MusicManager.Presentation/Services/FileService.cs b/src/MusicManager/MusicManager.Presentation/Services/FileService.cs index 9dc8208..0631e96 100644 --- a/src/MusicManager/MusicManager.Presentation/Services/FileService.cs +++ b/src/MusicManager/MusicManager.Presentation/Services/FileService.cs @@ -1,7 +1,6 @@ using System.ComponentModel.Composition; using System.IO; using System.Web; -using Waf.MusicManager.Applications.DataModels; using Waf.MusicManager.Applications.Services; using Windows.Media.Playlists; using Windows.Storage; diff --git a/src/MusicManager/MusicManager.Presentation/Services/MusicFileContext.cs b/src/MusicManager/MusicManager.Presentation/Services/MusicFileContext.cs index 0239b32..e38be85 100644 --- a/src/MusicManager/MusicManager.Presentation/Services/MusicFileContext.cs +++ b/src/MusicManager/MusicManager.Presentation/Services/MusicFileContext.cs @@ -19,8 +19,8 @@ internal class MusicFileContext : IMusicFileContext [ImportingConstructor] public MusicFileContext(IFileSystemWatcherService fileSystemWatcherService, ITranscodingService transcodingService) { - musicFilesCache = new ConcurrentDictionary>(); - runningTranscodingTasks = new ConcurrentDictionary(); + musicFilesCache = []; + runningTranscodingTasks = []; stopwatch = Stopwatch.StartNew(); fileSystemWatcherService.Renamed += FileSystemWatcherServiceRenamed; @@ -42,7 +42,7 @@ public MusicFile Create(string fileName) runningTranscodingTasks.TryGetValue(fileName, out var runningTranscodingTask); var musicFile = new MusicFile(x => LoadMetadata(x ?? throw new InvalidOperationException("MusicFile does not contain a file name"), runningTranscodingTask)!, fileName); - if (!musicFilesCache.TryAdd(fileName, new WeakReference(musicFile))) throw new InvalidOperationException("Race condition: This should not happen."); + if (!musicFilesCache.TryAdd(fileName, new(musicFile))) throw new InvalidOperationException("Race condition: This should not happen."); return musicFile; } @@ -74,17 +74,17 @@ private static async Task LoadMetadataFromMultiple(IReadOnlyList< return new MusicMetadata(duration, bitrate) { Title = GetSharedValueOrDefault(musicFiles, x => x.Title) ?? "", - Artists = GetSharedValueOrDefault>(musicFiles, x => x.Artists, SequenceEqualityComparer.Default) ?? Array.Empty(), + Artists = GetSharedValueOrDefault>(musicFiles, x => x.Artists, SequenceEqualityComparer.Default) ?? [], Rating = GetSharedValueOrDefault(musicFiles, x => x.Rating), Album = GetSharedValueOrDefault(musicFiles, x => x.Album) ?? "", TrackNumber = GetSharedValueOrDefault(musicFiles, x => x.TrackNumber), Year = GetSharedValueOrDefault(musicFiles, x => x.Year), - Genre = GetSharedValueOrDefault>(musicFiles, x => x.Genre, SequenceEqualityComparer.Default) ?? Array.Empty(), + Genre = GetSharedValueOrDefault>(musicFiles, x => x.Genre, SequenceEqualityComparer.Default) ?? [], AlbumArtist = GetSharedValueOrDefault(musicFiles, x => x.AlbumArtist) ?? "", Publisher = GetSharedValueOrDefault(musicFiles, x => x.Publisher) ?? "", Subtitle = GetSharedValueOrDefault(musicFiles, x => x.Subtitle) ?? "", - Composers = GetSharedValueOrDefault>(musicFiles, x => x.Composers, SequenceEqualityComparer.Default) ?? Array.Empty(), - Conductors = GetSharedValueOrDefault>(musicFiles, x => x.Conductors, SequenceEqualityComparer.Default) ?? Array.Empty() + Composers = GetSharedValueOrDefault>(musicFiles, x => x.Composers, SequenceEqualityComparer.Default) ?? [], + Conductors = GetSharedValueOrDefault>(musicFiles, x => x.Conductors, SequenceEqualityComparer.Default) ?? [] }; } @@ -94,7 +94,7 @@ public void ApplyChanges(MusicFile musicFile) var metadata = musicFile.Metadata; var changedProperties = metadata.Changes; - foreach (var sharedMetadata in musicFile.SharedMusicFiles.Select(x => GetMetadata(x))) + foreach (var sharedMetadata in musicFile.SharedMusicFiles.Select(GetMetadata)) { if (changedProperties.Contains(nameof(MusicMetadata.Artists))) { sharedMetadata.Artists = metadata.Artists; } if (changedProperties.Contains(nameof(MusicMetadata.Title))) { sharedMetadata.Title = metadata.Title; } diff --git a/src/MusicManager/MusicManager.Presentation/Services/SequenceEqualityComparer.cs b/src/MusicManager/MusicManager.Presentation/Services/SequenceEqualityComparer.cs index 31f710b..b172de5 100644 --- a/src/MusicManager/MusicManager.Presentation/Services/SequenceEqualityComparer.cs +++ b/src/MusicManager/MusicManager.Presentation/Services/SequenceEqualityComparer.cs @@ -2,7 +2,7 @@ internal class SequenceEqualityComparer : IEqualityComparer> { - public static SequenceEqualityComparer Default { get; } = new SequenceEqualityComparer(); + public static SequenceEqualityComparer Default { get; } = new(); public bool Equals(IEnumerable? x, IEnumerable? y) { diff --git a/src/MusicManager/MusicManager.Presentation/Services/StringListConverter.cs b/src/MusicManager/MusicManager.Presentation/Services/StringListConverter.cs index ba6171a..71591b2 100644 --- a/src/MusicManager/MusicManager.Presentation/Services/StringListConverter.cs +++ b/src/MusicManager/MusicManager.Presentation/Services/StringListConverter.cs @@ -4,7 +4,7 @@ namespace Waf.MusicManager.Presentation.Services; public static class StringListConverter { - public static string ToString(IEnumerable? list, string? separator = null) => string.Join(GetSeparator(separator), list ?? Array.Empty()); + public static string ToString(IEnumerable? list, string? separator = null) => string.Join(GetSeparator(separator), list ?? []); public static IReadOnlyList FromString(string text, string? separator = null) { diff --git a/src/MusicManager/MusicManager.Presentation/Services/SupportedFileTypes.cs b/src/MusicManager/MusicManager.Presentation/Services/SupportedFileTypes.cs index fb3bd7a..f9d0fb4 100644 --- a/src/MusicManager/MusicManager.Presentation/Services/SupportedFileTypes.cs +++ b/src/MusicManager/MusicManager.Presentation/Services/SupportedFileTypes.cs @@ -5,7 +5,7 @@ namespace Waf.MusicManager.Presentation.Services; internal static class SupportedFileTypes { - private static readonly string[] musicFileExtensions = { ".mp3", ".wma", ".wav", ".m4a", ".mp4" }; + private static readonly string[] musicFileExtensions = [ ".mp3", ".wma", ".wav", ".m4a", ".mp4" ]; private static readonly Mp3ReadMetadata mp3ReadMetadata = new(); private static readonly WmaReadMetadata wmaReadMetadata = new(); diff --git a/src/MusicManager/MusicManager.Presentation/Views/ManagerView.xaml.cs b/src/MusicManager/MusicManager.Presentation/Views/ManagerView.xaml.cs index 4cfdead..f60224a 100644 --- a/src/MusicManager/MusicManager.Presentation/Views/ManagerView.xaml.cs +++ b/src/MusicManager/MusicManager.Presentation/Views/ManagerView.xaml.cs @@ -23,15 +23,14 @@ public partial class ManagerView : IManagerView public ManagerView() { InitializeComponent(); - viewModel = new Lazy(() => this.GetViewModel()!); - autoColumns = new List() - { + viewModel = new(() => this.GetViewModel()!); + autoColumns = [ ratingColumn, genreColumn, yearColumn, albumColumn, trackNoColumn - }; + ]; autoColumns.ForEach(x => x.Visibility = Visibility.Collapsed); Loaded += LoadedHandler; @@ -66,7 +65,7 @@ private void DataGridRowMouseMove(object sender, MouseEventArgs e) { var draggedItem = (DataGridRow)sender; var items = musicFilesGrid.ItemsSource.Cast().ToList(); - var selectedItems = musicFilesGrid.SelectedItems.Cast().OrderBy(x => items.IndexOf(x)).ToArray(); + var selectedItems = musicFilesGrid.SelectedItems.Cast().OrderBy(items.IndexOf).ToArray(); DragDrop.DoDragDrop(draggedItem, selectedItems.Select(x => x.MusicFile).ToArray(), DragDropEffects.Copy); } } diff --git a/src/MusicManager/MusicManager.Presentation/Views/PlayerView.xaml.cs b/src/MusicManager/MusicManager.Presentation/Views/PlayerView.xaml.cs index b46610e..8ca5b0e 100644 --- a/src/MusicManager/MusicManager.Presentation/Views/PlayerView.xaml.cs +++ b/src/MusicManager/MusicManager.Presentation/Views/PlayerView.xaml.cs @@ -34,20 +34,20 @@ public partial class PlayerView : IPlayerView public PlayerView(PlayerService playerService) { InitializeComponent(); - viewModel = new Lazy(() => this.GetViewModel()!); + viewModel = new(() => this.GetViewModel()!); this.playerService = playerService; transportControls = Windows.Media.Playback.BackgroundMediaPlayer.Current.SystemMediaTransportControls; - mediaPlayer = new MediaPlayer(); - duratonConverter = new Converters.DurationConverter(); + mediaPlayer = new(); + duratonConverter = new(); updateTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(100) }; updateTimer.Tick += UpdateTimerTick; - throttledSliderValueChangedAction = new ThrottledAction(ThrottledSliderValueChanged, ThrottledActionMode.InvokeMaxEveryDelayTime, TimeSpan.FromMilliseconds(100)); + throttledSliderValueChangedAction = new(ThrottledSliderValueChanged, ThrottledActionMode.InvokeMaxEveryDelayTime, TimeSpan.FromMilliseconds(100)); - previousCommand = new DelegateCommand(Previous, CanPrevious); - playPauseCommand = new DelegateCommand(PlayPause, CanPlayPause); - nextCommand = new DelegateCommand(Next, CanNext); + previousCommand = new(Previous, CanPrevious); + playPauseCommand = new(PlayPause, CanPlayPause); + nextCommand = new(Next, CanNext); playerService.PreviousCommand = previousCommand; playerService.PlayPauseCommand = playPauseCommand; playerService.NextCommand = nextCommand; diff --git a/src/MusicManager/MusicManager.Presentation/Views/PlaylistView.xaml.cs b/src/MusicManager/MusicManager.Presentation/Views/PlaylistView.xaml.cs index 77c3bce..c7d1d3a 100644 --- a/src/MusicManager/MusicManager.Presentation/Views/PlaylistView.xaml.cs +++ b/src/MusicManager/MusicManager.Presentation/Views/PlaylistView.xaml.cs @@ -21,8 +21,8 @@ public partial class PlaylistView : IPlaylistView public PlaylistView() { InitializeComponent(); - viewModel = new Lazy(() => this.GetViewModel()!); - listBoxDragDropHelper = new ListBoxDragDropHelper(playlistListBox, MoveItems, TryGetInsertItems, InsertItems); + viewModel = new(() => this.GetViewModel()!); + listBoxDragDropHelper = new(playlistListBox, MoveItems, TryGetInsertItems, InsertItems); Loaded += FirstTimeLoadedHandler; } diff --git a/src/MusicManager/MusicManager.Presentation/Views/ShellWindow.xaml.cs b/src/MusicManager/MusicManager.Presentation/Views/ShellWindow.xaml.cs index da85883..68af513 100644 --- a/src/MusicManager/MusicManager.Presentation/Views/ShellWindow.xaml.cs +++ b/src/MusicManager/MusicManager.Presentation/Views/ShellWindow.xaml.cs @@ -18,7 +18,7 @@ public partial class ShellWindow : IShellView public ShellWindow() { InitializeComponent(); - viewModel = new Lazy(() => this.GetViewModel()!); + viewModel = new(() => this.GetViewModel()!); Loaded += LoadedHandler; // Workaround: Need to load both DrawingImages now; otherwise the first one is not shown at the beginning. diff --git a/src/MusicManager/MusicManager.Presentation/Views/TranscodingListView.xaml.cs b/src/MusicManager/MusicManager.Presentation/Views/TranscodingListView.xaml.cs index 6ea1a8f..fb09487 100644 --- a/src/MusicManager/MusicManager.Presentation/Views/TranscodingListView.xaml.cs +++ b/src/MusicManager/MusicManager.Presentation/Views/TranscodingListView.xaml.cs @@ -21,8 +21,8 @@ public partial class TranscodingListView : ITranscodingListView public TranscodingListView() { InitializeComponent(); - viewModel = new Lazy(() => this.GetViewModel()!); - listBoxDragDropHelper = new ListBoxDragDropHelper(transcodingListBox, null, TryGetInsertItems, InsertItems); + viewModel = new(() => this.GetViewModel()!); + listBoxDragDropHelper = new(transcodingListBox, null, TryGetInsertItems, InsertItems); Loaded += FirstTimeLoadedHandler; } @@ -43,8 +43,8 @@ private void FirstTimeLoadedHandler(object sender, RoutedEventArgs e) var statusGroupDescription = new PropertyGroupDescription(nameof(TranscodeItem.TranscodeStatus)); transcodeItemsCollectionView.GroupDescriptions.Add(statusGroupDescription); - foreach (var x in ViewModel.TranscodingManager.TranscodeItems) PropertyChangedEventManager.AddHandler(x, TranscodeItemPropertyChanged, ""); - CollectionChangedEventManager.AddHandler(ViewModel.TranscodingManager.TranscodeItems, TranscodeItemsCollectionChanged); + ViewModel.TranscodingManager.TranscodeItems.CollectionChanged += TranscodeItemsCollectionChanged; + ViewModel.TranscodingManager.TranscodeItems.CollectionItemChanged += TranscodeItemPropertyChanged; } private static IEnumerable? TryGetInsertItems(DragEventArgs e) => e.Data.GetData(DataFormats.FileDrop) as IEnumerable ?? e.Data.GetData(typeof(MusicFile[])) as IEnumerable; @@ -63,16 +63,10 @@ private void InsertItems(int index, IEnumerable itemsToInsert) private void TranscodeItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e) { - if (e.Action == NotifyCollectionChangedAction.Remove) + if (e.Action == NotifyCollectionChangedAction.Add) { - foreach (var x in e.OldItems!.Cast()) PropertyChangedEventManager.RemoveHandler(x, TranscodeItemPropertyChanged, ""); - } - else if (e.Action == NotifyCollectionChangedAction.Add) - { - foreach (var x in e.NewItems!.Cast()) PropertyChangedEventManager.AddHandler(x, TranscodeItemPropertyChanged, ""); transcodingListBox.ScrollIntoView(ViewModel.TranscodingManager.TranscodeItems[^1]); } - else throw new NotSupportedException("This action type is not supported: " + e.Action); transcodeItemsCollectionView.Refresh(); // Workaround because live shaping does not support to sort groupings. }