diff --git a/src/Client/App.axaml.cs b/src/Client/App.axaml.cs index 94c0423..2be2dea 100644 --- a/src/Client/App.axaml.cs +++ b/src/Client/App.axaml.cs @@ -4,6 +4,7 @@ using Autofac; using Avalonia; +using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Markup.Xaml; using WillowTree.Sweetgum.Client.DependencyInjection; @@ -35,6 +36,13 @@ public override void Initialize() /// public override void OnFrameworkInitializationCompleted() { + if (Design.IsDesignMode) + { + // The Visual Studio designer doesn't run our entry point, so DI and services haven't been set up. + // Do this now. + Dependencies.ConfigureServices(); + } + var settingsManager = Dependencies.Container.Resolve(); settingsManager.Load(); diff --git a/src/Client/ViewModels/MainWindowViewModel.cs b/src/Client/ViewModels/MainWindowViewModel.cs index 2dcdc46..db4e965 100644 --- a/src/Client/ViewModels/MainWindowViewModel.cs +++ b/src/Client/ViewModels/MainWindowViewModel.cs @@ -2,6 +2,7 @@ // Copyright (c) WillowTree, LLC. All rights reserved. // +using System; using System.Reactive; using System.Reactive.Linq; using System.Threading; @@ -23,10 +24,10 @@ public sealed class MainWindowViewModel : ReactiveObject public MainWindowViewModel() { this.NewWorkbookCommand = ReactiveCommand.CreateFromTask(this.NewWorkbookAsync); - this.NewWorkbookSpecifyPathInteraction = new Interaction(); + this.NewWorkbookSpecifyPathInteraction = new Interaction(); this.LoadWorkbookCommand = ReactiveCommand.CreateFromTask(this.LoadWorkbookAsync); - this.LoadWorkbookSpecifyPathInteraction = new Interaction(); + this.LoadWorkbookSpecifyPathInteraction = new Interaction(); this.OpenSettingsCommand = ReactiveCommand.Create(() => { }); } @@ -49,12 +50,12 @@ public MainWindowViewModel() /// /// Gets the interaction to specify a path for a new workbook. /// - public Interaction NewWorkbookSpecifyPathInteraction { get; } + public Interaction NewWorkbookSpecifyPathInteraction { get; } /// /// Gets the interaction to specify a path for an existing workbook. /// - public Interaction LoadWorkbookSpecifyPathInteraction { get; } + public Interaction LoadWorkbookSpecifyPathInteraction { get; } private async Task NewWorkbookAsync( Unit input, @@ -62,6 +63,12 @@ private async Task NewWorkbookAsync( { var path = await this.NewWorkbookSpecifyPathInteraction.Handle(Unit.Default); + if (string.IsNullOrEmpty(path)) + { + // We don't have access to the observable subscription or CTS here since it's eaten by Avalonia. + throw new TaskCanceledException(); + } + return await WorkbookManager.NewAsync(path, cancellationToken); } @@ -71,6 +78,12 @@ private async Task LoadWorkbookAsync( { var path = await this.LoadWorkbookSpecifyPathInteraction.Handle(Unit.Default); + if (string.IsNullOrEmpty(path)) + { + // We don't have access to the observable subscription or CTS here since it's eaten by Avalonia. + throw new TaskCanceledException(); + } + return await WorkbookManager.LoadAsync(path, cancellationToken); } } diff --git a/src/Client/Views/ErrorDialog.axaml b/src/Client/Views/ErrorDialog.axaml new file mode 100644 index 0000000..2c23a42 --- /dev/null +++ b/src/Client/Views/ErrorDialog.axaml @@ -0,0 +1,22 @@ + + + + + + + + + + +