first commit
This commit is contained in:
50
Nitrox.Launcher/ViewModels/Abstract/ModalViewModelBase.cs
Normal file
50
Nitrox.Launcher/ViewModels/Abstract/ModalViewModelBase.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.Linq;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls.ApplicationLifetimes;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using HanumanInstitute.MvvmDialogs;
|
||||
using Nitrox.Launcher.Models;
|
||||
|
||||
namespace Nitrox.Launcher.ViewModels.Abstract;
|
||||
|
||||
/// <summary>
|
||||
/// Base class for (popup) dialog ViewModels.
|
||||
/// </summary>
|
||||
public abstract partial class ModalViewModelBase : ObservableValidator, IModalDialogViewModel, IMessageReceiver
|
||||
{
|
||||
[ObservableProperty] private ButtonOptions? selectedOption;
|
||||
|
||||
bool? IModalDialogViewModel.DialogResult => (bool)this;
|
||||
|
||||
protected ModalViewModelBase()
|
||||
{
|
||||
// Always run validation first so HasErrors is set (i.e. trigger CanExecute logic).
|
||||
ValidateAllProperties();
|
||||
}
|
||||
|
||||
public static implicit operator bool(ModalViewModelBase self)
|
||||
{
|
||||
return self is { HasErrors: false } and not { SelectedOption: null or ButtonOptions.No };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Closes the dialog window. By default, sets the dialog result as cancelled.
|
||||
/// </summary>
|
||||
/// <param name="buttonOptions">The dialog result to set before closing.</param>
|
||||
[RelayCommand]
|
||||
public void Close(ButtonOptions? buttonOptions = null)
|
||||
{
|
||||
if (buttonOptions != null)
|
||||
{
|
||||
SelectedOption = buttonOptions;
|
||||
}
|
||||
((IClassicDesktopStyleApplicationLifetime)Application.Current?.ApplicationLifetime)?.Windows.FirstOrDefault(w => w.DataContext == this)?.CloseByUser();
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
}
|
||||
}
|
16
Nitrox.Launcher/ViewModels/Abstract/RoutableViewModelBase.cs
Normal file
16
Nitrox.Launcher/ViewModels/Abstract/RoutableViewModelBase.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using System.Threading.Tasks;
|
||||
using Nitrox.Launcher.Models.Design;
|
||||
|
||||
namespace Nitrox.Launcher.ViewModels.Abstract;
|
||||
|
||||
public abstract class RoutableViewModelBase : ViewModelBase
|
||||
{
|
||||
public IRoutingScreen HostScreen { get; } = AppViewLocator.HostScreen;
|
||||
|
||||
/// <summary>
|
||||
/// Loads content that the view should show. While the returned task is running a loading indicator will be visible.
|
||||
/// </summary>
|
||||
internal virtual Task ViewContentLoadAsync() => Task.CompletedTask;
|
||||
|
||||
internal virtual Task ViewContentUnloadAsync() => Task.CompletedTask;
|
||||
}
|
48
Nitrox.Launcher/ViewModels/Abstract/ViewModelBase.cs
Normal file
48
Nitrox.Launcher/ViewModels/Abstract/ViewModelBase.cs
Normal file
@@ -0,0 +1,48 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Avalonia.Controls;
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Nitrox.Launcher.Models;
|
||||
|
||||
namespace Nitrox.Launcher.ViewModels.Abstract;
|
||||
|
||||
public abstract class ViewModelBase : ObservableValidator, IMessageReceiver
|
||||
{
|
||||
protected Window MainWindow => AppViewLocator.MainWindow;
|
||||
|
||||
protected ViewModelBase()
|
||||
{
|
||||
ThrowIfViewModelCtorWasEmptyWhileNonEmptyExists();
|
||||
}
|
||||
|
||||
public virtual void Dispose() => WeakReferenceMessenger.Default.UnregisterAll(this);
|
||||
|
||||
/// <summary>
|
||||
/// This will check that DI did not call the empty ViewModel constructor if dependencies for another constructor aren't met.
|
||||
/// </summary>
|
||||
[Conditional("DEBUG")]
|
||||
private static void ThrowIfViewModelCtorWasEmptyWhileNonEmptyExists()
|
||||
{
|
||||
if (Design.IsDesignMode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
foreach (StackFrame stackFrame in new StackTrace(2, false).GetFrames())
|
||||
{
|
||||
if (stackFrame.GetMethod() is not { IsConstructor: true } method)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (method.DeclaringType is not { IsAbstract: false } declaringType)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (method.GetParameters().Length > 0 || declaringType.GetConstructors().Length == 1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
throw new Exception($"Empty ViewModel constructor of '{declaringType.Name}' should only be used in design mode! Check that the DI-container has all the dependencies to call a different constructor.");
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user