diff --git a/Core/Models/TagDatabase/TagDatabase.DeleteMethods.cs b/Core/Models/TagDatabase/TagDatabase.DeleteMethods.cs
index 9b4f7ea..d517dcc 100644
--- a/Core/Models/TagDatabase/TagDatabase.DeleteMethods.cs
+++ b/Core/Models/TagDatabase/TagDatabase.DeleteMethods.cs
@@ -69,7 +69,7 @@ partial class TagDatabase
tag.Parents.Remove(targetTag.Name);
});
- Tag cachedTag = this.Tags.FirstOrDefault(t => t.Id == targetTag.Id);
+ Tag? cachedTag = this.Tags.FirstOrDefault(t => t.Id == targetTag.Id);
if (cachedTag != null)
{
this.Tags.Remove(cachedTag);
diff --git a/Core/TagHierarchyManager.csproj b/Core/TagHierarchyManager.csproj
index 9127e84..7dcc757 100644
--- a/Core/TagHierarchyManager.csproj
+++ b/Core/TagHierarchyManager.csproj
@@ -6,7 +6,6 @@
enable
enable
false
- true
true
diff --git a/UI/ViewModels/ErrorDialogViewModel.cs b/UI/ViewModels/ErrorDialogViewModel.cs
index f91d0cf..c2272d9 100644
--- a/UI/ViewModels/ErrorDialogViewModel.cs
+++ b/UI/ViewModels/ErrorDialogViewModel.cs
@@ -26,7 +26,10 @@ public partial class ErrorDialogViewModel : ViewModelBase
DataContext = this,
Title = Resources.ErrorDialogTitle
};
+ error.Closed += (_, _) => error.DataContext = null;
+
var ownerWindow = desktop.Windows.FirstOrDefault(w => w.IsActive) ?? desktop.MainWindow;
- error.ShowDialog(ownerWindow);
+ if (ownerWindow == null) error.Show();
+ else error.ShowDialog(ownerWindow);
}
}
\ No newline at end of file
diff --git a/UI/ViewModels/HierarchyTreeViewModel.cs b/UI/ViewModels/HierarchyTreeViewModel.cs
index b49967f..e33e6f9 100644
--- a/UI/ViewModels/HierarchyTreeViewModel.cs
+++ b/UI/ViewModels/HierarchyTreeViewModel.cs
@@ -48,12 +48,12 @@ public partial class HierarchyTreeViewModel : ViewModelBase, IDisposable
viewModel = new TagItemViewModel(tag, id =>
this._viewModelMap.Values.FirstOrDefault(v => v.Id == id)?.Name);
this._viewModelMap[key] = viewModel;
- viewModel.UserEditedTag += (s, e) => this._mainWindow.UnsavedChanges = true;
+ viewModel.UserEditedTag += this.OnUserEditedTag;
}
return viewModel;
}
-
+
partial void OnSelectedTagChanged(TagItemViewModel? value)
{
this._mainWindow.SelectedTag = value;
@@ -67,6 +67,8 @@ public partial class HierarchyTreeViewModel : ViewModelBase, IDisposable
});
await this.SyncHierarchyAsync();
}
+
+ private void OnUserEditedTag(object? sender, EventArgs e) => this._mainWindow.UnsavedChanges = true;
private void SubscribeToEvents()
{
@@ -95,7 +97,6 @@ public partial class HierarchyTreeViewModel : ViewModelBase, IDisposable
}
}
-
private async Task SyncHierarchyAsync()
{
if (this._mainWindow.Database is null) return;
@@ -123,7 +124,11 @@ public partial class HierarchyTreeViewModel : ViewModelBase, IDisposable
this.SyncCollection(this.TopLevelTags, topLevelViewModels);
var keysToRemove = this._viewModelMap.Keys.Where(k => !activeKeys.Contains(k)).ToList();
- foreach (var key in keysToRemove) this._viewModelMap.Remove(key);
+ foreach (var key in keysToRemove)
+ {
+ this._viewModelMap[key].UserEditedTag -= this.OnUserEditedTag;
+ this._viewModelMap.Remove(key);
+ }
}
private void SyncTagRecursive(TagItemViewModel parentVm, ILookup childrenLookup,
diff --git a/UI/ViewModels/ImportDialogViewModel.cs b/UI/ViewModels/ImportDialogViewModel.cs
index c09bc41..27e5599 100644
--- a/UI/ViewModels/ImportDialogViewModel.cs
+++ b/UI/ViewModels/ImportDialogViewModel.cs
@@ -5,24 +5,19 @@ using TagHierarchyManager.UI.Assets;
namespace TagHierarchyManager.UI.ViewModels;
-public partial class ImportDialogViewModel : ViewModelBase
+public partial class ImportDialogViewModel(MainWindowViewModel mainWindow) : ViewModelBase
{
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(VisibleDatabaseFilePath))]
[NotifyPropertyChangedFor(nameof(BothFilesSelected))]
- private string _databaseFilePath;
+ private string _databaseFilePath = string.Empty;
[ObservableProperty] private string _importStatus = string.Empty;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(VisibleTemplateFilePath))]
[NotifyPropertyChangedFor(nameof(BothFilesSelected))]
- private string _templateFilePath;
-
- public ImportDialogViewModel(MainWindowViewModel mainWindow)
- {
- this.MainWindow = mainWindow;
- }
+ private string _templateFilePath = string.Empty;
public event Action? RequestClose;
@@ -35,7 +30,7 @@ public partial class ImportDialogViewModel : ViewModelBase
public string VisibleTemplateFilePath =>
!string.IsNullOrWhiteSpace(this.TemplateFilePath) ? this.TemplateFilePath : Resources.ImportNoFilePicked;
- private MainWindowViewModel MainWindow { get; }
+ private MainWindowViewModel MainWindow { get; } = mainWindow;
public async Task InitiateImport()
{
diff --git a/UI/ViewModels/MainWindowViewModel.cs b/UI/ViewModels/MainWindowViewModel.cs
index a14e0f2..92214ec 100644
--- a/UI/ViewModels/MainWindowViewModel.cs
+++ b/UI/ViewModels/MainWindowViewModel.cs
@@ -42,7 +42,7 @@ public partial class MainWindowViewModel : ViewModelBase
public int TotalTags => this.Database?.Tags.Count ?? 0;
public string WindowTitle =>
- this.IsDbEnabled
+ this.Database is not null
? string.Format(Resources.TitleWithDatabase, this.Database?.Name)
: Resources.Title;
@@ -52,7 +52,7 @@ public partial class MainWindowViewModel : ViewModelBase
set
{
if (this._selectedTag == value || this._isSwitching) return;
- if (!this.IsDbEnabled && value == null) this._selectedTag = value;
+ if (value == null) this._selectedTag = value;
if (this._selectedTag != null && this.UnsavedChanges)
{
_ = this.HandleTagSwitchAsync(this._selectedTag, value);
@@ -101,23 +101,14 @@ public partial class MainWindowViewModel : ViewModelBase
public async Task ExportAsync(string path)
{
+ if (this.Database is null || string.IsNullOrWhiteSpace(path)) return;
this.IsDbEnabled = false;
- try
- {
- if (this.Database is null || string.IsNullOrWhiteSpace(path)) return;
-
- var exporter = PickExporterFromFileExt(path);
- this.StatusBlockText = Resources.StatusBlockExportInProgress;
- var exportContent = await Task.Run(() => exporter.ExportDatabase(this.Database!));
- await File.WriteAllTextAsync(path, exportContent);
- this.IsDbEnabled = true;
- this.StatusBlockText = string.Format(Resources.StatusBlockExportSuccessful, path);
- }
- catch (Exception ex)
- {
- this.IsDbEnabled = true;
- this.ShowErrorDialog(ex.Message);
- }
+ var exporter = PickExporterFromFileExt(path);
+ this.StatusBlockText = Resources.StatusBlockExportInProgress;
+ var exportContent = await Task.Run(() => exporter.ExportDatabase(this.Database!));
+ await File.WriteAllTextAsync(path, exportContent);
+ this.IsDbEnabled = true;
+ this.StatusBlockText = string.Format(Resources.StatusBlockExportSuccessful, path);
}
public async Task LoadDatabase(string filePath)
@@ -153,19 +144,12 @@ public partial class MainWindowViewModel : ViewModelBase
public async Task SaveSelectedTagAsync()
{
if (this.SelectedTag is null || this.Database is null) return;
-
- try
- {
- this.SelectedTag.CommitEdit();
- await this.Database.WriteTagToDatabase(this.SelectedTag.Tag);
- this.SelectedTag.RefreshParentsString();
- this.StatusBlockText = string.Format(Resources.StatusBlockTagSaveSuccessful, this.SelectedTag.Name);
- this.UnsavedChanges = false;
- }
- catch (Exception ex)
- {
- this.ShowErrorDialog(ex.Message);
- }
+
+ this.SelectedTag.CommitEdit();
+ await this.Database.WriteTagToDatabase(this.SelectedTag.Tag);
+ this.SelectedTag.RefreshParentsString();
+ this.StatusBlockText = string.Format(Resources.StatusBlockTagSaveSuccessful, this.SelectedTag.Name);
+ this.UnsavedChanges = false;
}
public void ShowDatabaseSettings()
@@ -181,12 +165,6 @@ public partial class MainWindowViewModel : ViewModelBase
dialog.ShowDialog(desktop.MainWindow!);
}
- public void ShowErrorDialog(string message)
- {
- var error = new ErrorDialogViewModel(message);
- error.ShowDialog();
- }
-
public void ShowImportDialog()
{
if (Application.Current?.ApplicationLifetime is not IClassicDesktopStyleApplicationLifetime desktop)
@@ -331,6 +309,12 @@ public partial class MainWindowViewModel : ViewModelBase
});
Debug.WriteLine($"Database loaded on UI - name: {db.Name}, version: {db.Version}");
}
+
+ private void ShowErrorDialog(string message)
+ {
+ var error = new ErrorDialogViewModel(message);
+ error.ShowDialog();
+ }
private void TagDatabase_TagAdded(object? sender, Tag _)
{
diff --git a/UI/ViewModels/SearchViewModel.cs b/UI/ViewModels/SearchViewModel.cs
index 7f6e957..e884cda 100644
--- a/UI/ViewModels/SearchViewModel.cs
+++ b/UI/ViewModels/SearchViewModel.cs
@@ -9,7 +9,7 @@ namespace TagHierarchyManager.UI.ViewModels;
public partial class SearchViewModel : ViewModelBase, IDisposable
{
- private readonly MainWindowViewModel mainWindow;
+ private readonly MainWindowViewModel _mainWindow;
[ObservableProperty] private ObservableCollection _searchResults = [];
@@ -17,34 +17,34 @@ public partial class SearchViewModel : ViewModelBase, IDisposable
public SearchViewModel(MainWindowViewModel mainWindow)
{
- this.mainWindow = mainWindow;
- mainWindow.Database.TagDeleted += this.TagDatabase_OnTagDeleted;
+ this._mainWindow = mainWindow;
+ mainWindow.Database?.TagDeleted += this.TagDatabase_OnTagDeleted;
}
- public void Dispose() => this.mainWindow.Database?.TagDeleted -= this.TagDatabase_OnTagDeleted;
+ public void Dispose() => this._mainWindow.Database?.TagDeleted -= this.TagDatabase_OnTagDeleted;
public void Search(string searchQuery, TagDatabaseSearchMode mode, bool searchAliases)
{
- if (this.mainWindow.Database == null || string.IsNullOrWhiteSpace(searchQuery)) return;
+ if (this._mainWindow.Database == null || string.IsNullOrWhiteSpace(searchQuery)) return;
var results = searchAliases
- ? this.mainWindow.Database.SearchWithAliases(searchQuery, mode)
- : this.mainWindow.Database.Search(searchQuery, mode);
+ ? this._mainWindow.Database.SearchWithAliases(searchQuery, mode)
+ : this._mainWindow.Database.Search(searchQuery, mode);
this.SearchResults.Clear();
if (results.Count == 0)
{
- this.mainWindow.StatusBlockText = Resources.SearchNoResultsFound;
+ this._mainWindow.StatusBlockText = Resources.SearchNoResultsFound;
return;
}
results.Select(tag =>
- new TagItemViewModel(tag, id => this.mainWindow.Database.Tags.FirstOrDefault(t => t.Id == id)?.Name))
+ new TagItemViewModel(tag, id => this._mainWindow.Database.Tags.FirstOrDefault(t => t.Id == id)?.Name))
.OrderBy(tag => tag.Name)
.ToList()
.ForEach(this.SearchResults.Add);
- this.mainWindow.StatusBlockText = results.Count > 1
+ this._mainWindow.StatusBlockText = results.Count > 1
? string.Format(Resources.SearchMultipleResultsFound, results.Count)
: Resources.SearchOneResultFound;
}
@@ -52,7 +52,7 @@ public partial class SearchViewModel : ViewModelBase, IDisposable
partial void OnSelectedSearchResultChanged(TagItemViewModel? value)
{
if (value is null) return;
- this.mainWindow.SelectedTag = value;
+ this._mainWindow.SelectedTag = value;
}
private void TagDatabase_OnTagDeleted(object? sender, (int id, string name) deletedTag)
diff --git a/UI/ViewModels/TagItemViewModel.cs b/UI/ViewModels/TagItemViewModel.cs
index 78654dd..1a4cfa7 100644
--- a/UI/ViewModels/TagItemViewModel.cs
+++ b/UI/ViewModels/TagItemViewModel.cs
@@ -11,17 +11,17 @@ namespace TagHierarchyManager.UI.ViewModels;
public partial class TagItemViewModel(Tag tag, Func? getNameById = null) : ViewModelBase
{
- [ObservableProperty] private string _editingAliases;
+ [ObservableProperty] private string _editingAliases = string.Empty;
[ObservableProperty] private bool _editingIsTopLevel;
[ObservableProperty] private string _editingName = tag.Name;
- [ObservableProperty] private string _editingNotes;
+ [ObservableProperty] private string _editingNotes = string.Empty;
- [ObservableProperty] private string _editingParents;
+ [ObservableProperty] private string _editingParents = string.Empty;
- [ObservableProperty] private string _editingTagBindings;
+ [ObservableProperty] private string _editingTagBindings = string.Empty;
private bool _isInitialising;
diff --git a/UI/Views/Common.cs b/UI/Views/Common.cs
index 747d8ed..0aa25e2 100644
--- a/UI/Views/Common.cs
+++ b/UI/Views/Common.cs
@@ -3,7 +3,7 @@ using TagHierarchyManager.UI.Assets;
namespace TagHierarchyManager.UI.Views;
-public class Common
+public static class Common
{
public static FilePickerFileType MusicBeeTagHierarchy { get; } = new(Resources.FileFormatMusicBeeTagHierarchy)
{
diff --git a/UI/Views/ImportDialog.axaml.cs b/UI/Views/ImportDialog.axaml.cs
index cd05bff..b2fb31c 100644
--- a/UI/Views/ImportDialog.axaml.cs
+++ b/UI/Views/ImportDialog.axaml.cs
@@ -11,10 +11,17 @@ public partial class ImportDialog : Window
public ImportDialog()
{
this.InitializeComponent();
- this.DataContextChanged += (s, e) =>
+
+ this.DataContextChanged += (_, _) =>
{
if (this.ViewModel != null) this.ViewModel.RequestClose += this.Close;
};
+
+ this.Unloaded += (_, _) =>
+ {
+ if (this.ViewModel != null)
+ this.ViewModel.RequestClose -= this.Close;
+ };
}
private ImportDialogViewModel? ViewModel => this.DataContext as ImportDialogViewModel;
@@ -68,6 +75,19 @@ public partial class ImportDialog : Window
public void ButtonCancel_Click(object? sender, RoutedEventArgs e) =>
this.Close();
- public async void ButtonImport_Click(object? sender, RoutedEventArgs e) =>
- await this.ViewModel?.InitiateImport();
+ public async void ButtonImport_Click(object? sender, RoutedEventArgs e)
+ {
+ try
+ {
+ if (this.ViewModel?.DatabaseFilePath == null || this.ViewModel?.TemplateFilePath == null ||
+ this.ViewModel is null) return;
+ await this.ViewModel.InitiateImport();
+ }
+ catch (Exception ex)
+ {
+ var error = new ErrorDialogViewModel(ex.Message);
+ error.ShowDialog();
+ }
+ }
+
}
\ No newline at end of file
diff --git a/UI/Views/MainWindow.axaml b/UI/Views/MainWindow.axaml
index b152251..3db912f 100644
--- a/UI/Views/MainWindow.axaml
+++ b/UI/Views/MainWindow.axaml
@@ -46,8 +46,8 @@
+ ItemsSource="{Binding HierarchyTreeViewModel.TopLevelTags, FallbackValue={x:Null}}"
+ SelectedItem="{Binding HierarchyTreeViewModel.SelectedTag, Mode=TwoWay, FallbackValue={x:Null}}">
@@ -106,30 +106,30 @@
RowDefinitions="Auto, Auto, Auto, Auto, *, Auto"
Margin="5"
IsEnabled="{Binding SelectedTag, Converter={x:Static ObjectConverters.IsNotNull}}">
-
-
-
-
-
-
diff --git a/UI/Views/MainWindow.axaml.cs b/UI/Views/MainWindow.axaml.cs
index 1ccaefa..d9b7bf7 100644
--- a/UI/Views/MainWindow.axaml.cs
+++ b/UI/Views/MainWindow.axaml.cs
@@ -1,3 +1,4 @@
+using System;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
@@ -20,50 +21,90 @@ public partial class MainWindow : Window
public void ButtonAdd_Click(object? sender, RoutedEventArgs e)
{
- this.ViewModel?.NewTag();
+ if (this.ViewModel?.SelectedTag is null) return;
+ this.ViewModel.NewTag();
}
public void ButtonCancel_Click(object? sender, RoutedEventArgs e)
{
- this.ViewModel?.SelectedTag.BeginEdit();
+ this.ViewModel?.SelectedTag?.BeginEdit();
}
public void ButtonDelete_Click(object? sender, RoutedEventArgs e)
{
- this.ViewModel?.StartTagDeletion();
+ try
+ {
+ if (this.ViewModel?.Database is null) return;
+ this.ViewModel?.StartTagDeletion();
+ }
+ catch (Exception ex)
+ {
+ var error = new ErrorDialogViewModel(ex.Message);
+ error.ShowDialog();
+ }
}
-
+
public async void ButtonSave_Click(object? sender, RoutedEventArgs e)
{
- await this.ViewModel?.SaveSelectedTagAsync();
+ try
+ {
+ if (this.ViewModel?.SelectedTag is null) return;
+ await this.ViewModel.SaveSelectedTagAsync();
+ }
+ catch (Exception ex)
+ {
+ var error = new ErrorDialogViewModel(ex.Message);
+ error.ShowDialog();
+ }
}
public void ButtonSearch_Click(object? sender, RoutedEventArgs e)
{
- this.ViewModel?.StartSearch(
- this.SearchTextBox.Text!,
- (TagDatabaseSearchMode)this.SearchModeComboBox.SelectedIndex,
- this.SearchAliasesCheckBox.IsChecked ?? false);
+ try
+ {
+ if (this.ViewModel?.Database is null) return;
+ this.ViewModel?.StartSearch(
+ this.SearchTextBox.Text!,
+ (TagDatabaseSearchMode)this.SearchModeComboBox.SelectedIndex,
+ this.SearchAliasesCheckBox.IsChecked ?? false);
+ }
+ catch (Exception ex)
+ {
+ var error = new ErrorDialogViewModel(ex.Message);
+ error.ShowDialog();
+ }
+
}
public void MenuItemDatabaseSettings_Click(object? sender, RoutedEventArgs e)
{
- this.ViewModel?.ShowDatabaseSettings();
+ if (this.ViewModel?.Database == null) return;
+ this.ViewModel.ShowDatabaseSettings();
}
+ // Resharper disable once AsyncVoidEventHandlerMethod
public async void MenuItemExport_Click(object? sender, RoutedEventArgs e)
{
- var file = await this.StorageProvider.SaveFilePickerAsync(
- new FilePickerSaveOptions
- {
- Title = Assets.Resources.DialogTitleExportTagDatabase,
- FileTypeChoices = [Common.MusicBeeTagHierarchy],
- SuggestedFileName = this.ViewModel?.Database.Name
- });
- if (file == null) return;
- var path = file.TryGetLocalPath();
- if (path == null) return;
- await this.ViewModel?.ExportAsync(path);
+ if (this.ViewModel?.Database == null) return;
+ try
+ {
+ var file = await this.StorageProvider.SaveFilePickerAsync(
+ new FilePickerSaveOptions
+ {
+ Title = Assets.Resources.DialogTitleExportTagDatabase,
+ FileTypeChoices = [Common.MusicBeeTagHierarchy],
+ SuggestedFileName = this.ViewModel.Database.Name
+ });
+ var path = file?.TryGetLocalPath();
+ if (path == null) return;
+ await this.ViewModel.ExportAsync(path);
+ }
+ catch (Exception ex)
+ {
+ this.ViewModel.IsDbEnabled = true;
+ var error = new ErrorDialogViewModel(ex.Message);
+ error.ShowDialog();
+ }
}
public void MenuItemImport_Click(object? sender, RoutedEventArgs e)
@@ -73,32 +114,48 @@ public partial class MainWindow : Window
public async void MenuItemNew_Click(object? sender, RoutedEventArgs e)
{
- if (this.ViewModel is null) return;
- var file = await this.StorageProvider.SaveFilePickerAsync(
- new FilePickerSaveOptions
- {
- Title = Assets.Resources.DialogTitleSaveDatabaseAs,
- FileTypeChoices = [Common.TagDatabaseFileType]
- });
- if (file == null) return;
- var path = file.TryGetLocalPath();
- if (path == null) return;
- await this.ViewModel.CreateNewDatabase(path);
+ try
+ {
+ if (this.ViewModel is null) return;
+ var file = await this.StorageProvider.SaveFilePickerAsync(
+ new FilePickerSaveOptions
+ {
+ Title = Assets.Resources.DialogTitleSaveDatabaseAs,
+ FileTypeChoices = [Common.TagDatabaseFileType]
+ });
+ var path = file?.TryGetLocalPath();
+ if (path == null) return;
+ await this.ViewModel.CreateNewDatabase(path);
+ }
+ catch (Exception ex)
+ {
+ var error = new ErrorDialogViewModel(ex.Message);
+ error.ShowDialog();
+ }
}
public async void MenuItemOpen_Click(object? sender, RoutedEventArgs e)
{
- var files = await this.StorageProvider.OpenFilePickerAsync(
- new FilePickerOpenOptions
- {
- AllowMultiple = false,
- Title = Assets.Resources.DialogTitleOpenDatabase,
- FileTypeFilter = [Common.TagDatabaseFileType]
- });
- if (files.Count == 0) return;
- var path = files[0].TryGetLocalPath();
- if (path == null) return;
- await this.ViewModel?.LoadDatabase(path);
+ try
+ {
+ if (this.ViewModel is null) return;
+ var files = await this.StorageProvider.OpenFilePickerAsync(
+ new FilePickerOpenOptions
+ {
+ AllowMultiple = false,
+ Title = Assets.Resources.DialogTitleOpenDatabase,
+ FileTypeFilter = [Common.TagDatabaseFileType]
+ });
+ if (files.Count == 0) return;
+ var path = files[0].TryGetLocalPath();
+ if (path == null) return;
+ await this.ViewModel.LoadDatabase(path);
+ }
+ catch (Exception ex)
+ {
+ var error = new ErrorDialogViewModel(ex.Message);
+ error.ShowDialog();
+ }
}
@@ -121,25 +178,38 @@ public partial class MainWindow : Window
public async void WindowClosing(object? sender, WindowClosingEventArgs e)
{
- if (this._userWantsToQuit) return;
- if (this.ViewModel.UnsavedChanges)
+ try
{
- e.Cancel = true;
- var result = await this.ViewModel.ShowNullableBoolDialog(new UnsavedChangesDialog());
- switch (result)
+ if (this._userWantsToQuit) return;
+ if (this.ViewModel is not null && this.ViewModel.UnsavedChanges)
{
- case true:
- await this.ViewModel.SaveSelectedTagAsync();
- this._userWantsToQuit = true;
- this.Close();
- break;
- case false:
- this._userWantsToQuit = true;
- this.Close();
- break;
- case null:
- break;
+ e.Cancel = true;
+ var result = await this.ViewModel.ShowNullableBoolDialog(new UnsavedChangesDialog());
+ switch (result)
+ {
+ case true:
+ await this.ViewModel.SaveSelectedTagAsync();
+ this._userWantsToQuit = true;
+ this.Close();
+ break;
+ case false:
+ this._userWantsToQuit = true;
+ this.Close();
+ break;
+ case null:
+ break;
+ }
}
+ else
+ {
+ this._userWantsToQuit = true;
+ this.Close();
+ }
+ }
+ catch (Exception ex)
+ {
+ var error = new ErrorDialogViewModel(ex.Message);
+ error.ShowDialog();
}
}
}
\ No newline at end of file