< Summary

Information
Class: MyNet.UI.ViewModels.Workspace.WorkspaceViewModel
Assembly: MyNet.UI
File(s): https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Workspace/WorkspaceViewModel.cs
Tag: 323_28699572109
Line coverage
77%
Covered lines: 24
Uncovered lines: 7
Coverable lines: 31
Total lines: 168
Line coverage: 77.4%
Branch coverage
60%
Covered branches: 6
Total branches: 10
Branch coverage: 60%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)50%6687.5%
set_Title(...)100%11100%
set_Mode(...)100%11100%
set_IsEnabled(...)100%210%
CanRefresh()100%210%
CanReset()100%210%
MyNet.UI.ILoadable.LoadAsync(...)100%11100%
RefreshAsync(...)100%11100%
ResetAsync(...)100%11100%
OnRefreshAsync(...)100%11100%
OnResetAsync(...)100%11100%
CreateTitle(...)100%11100%
OnEvent(...)100%210%
ApplyTitle(...)100%22100%
ScheduleInitialTitle(...)50%2266.66%

File(s)

https://raw.githubusercontent.com/sandre58/MyNet/85372080fe102cd9ee155ceab49ae000e7f66103/src/MyNet.UI/ViewModels/Workspace/WorkspaceViewModel.cs

#LineLine coverage
 1// -----------------------------------------------------------------------
 2// <copyright file="WorkspaceViewModel.cs" company="Stéphane ANDRE">
 3// Copyright (c) Stéphane ANDRE. All rights reserved.
 4// </copyright>
 5// -----------------------------------------------------------------------
 6
 7using System;
 8using System.Globalization;
 9using System.Threading;
 10using System.Threading.Tasks;
 11using System.Windows.Input;
 12using MyNet.Globalization.Culture;
 13using MyNet.Observable;
 14using MyNet.Observable.Behaviors.Metadata.Features.Events;
 15using MyNet.UI.Commands;
 16
 17namespace MyNet.UI.ViewModels.Workspace;
 18
 19/// <summary>
 20/// Provides a reusable base implementation for workspace view models.
 21/// </summary>
 22public class WorkspaceViewModel : ViewModelBase, IWorkspaceViewModel, IEventAware<CultureChangedEvent>
 23{
 24    /// <summary>
 25    /// Initializes a new instance of the <see cref="WorkspaceViewModel"/> class.
 26    /// </summary>
 27    /// <param name="commandFactory">Optional command factory used to create commands.</param>
 28    /// <param name="cultureService">Optional culture service used to manage culture changes.</param>
 13229    protected WorkspaceViewModel(
 13230        ICommandFactory? commandFactory = null,
 13231        ICultureService? cultureService = null)
 32    {
 13233        Commands = commandFactory.GetOrDefault();
 34
 35        RefreshCommand = Commands.Create(() => RefreshAsync(), CanRefresh);
 36        ResetCommand = Commands.Create(() => ResetAsync(), CanReset);
 37
 13238        if (cultureService is not null)
 39        {
 040            this.ReactOnCultureChanged(cultureService);
 41        }
 42
 13243        ScheduleInitialTitle(cultureService?.CurrentCulture ?? CultureInfo.CurrentUICulture);
 13244    }
 45
 46    /// <summary>
 47    /// Gets the command factory used by this workspace (never null).
 48    /// </summary>
 49    protected ICommandFactory Commands { get; }
 50
 51    /// <summary>
 52    /// Gets the command to refresh the workspace content.
 53    /// </summary>
 54    public ICommand RefreshCommand { get; }
 55
 56    /// <summary>
 57    /// Gets the command to reset the workspace state and content.
 58    /// </summary>
 59    public ICommand ResetCommand { get; }
 60
 61    /// <summary>
 62    /// Gets or sets the workspace title.
 63    /// </summary>
 64    public string? Title
 65    {
 66        get;
 67
 2768        set => SetProperty(ref field, value);
 69    }
 70
 71    /// <summary>
 72    /// Gets or sets the workspace display mode.
 73    /// </summary>
 1574    public ScreenMode Mode { get; set => SetProperty(ref field, value); } = ScreenMode.Unknown;
 75
 76    /// <summary>
 77    /// Gets or sets a value indicating whether the workspace is enabled.
 78    /// </summary>
 079    public bool IsEnabled { get; set => SetProperty(ref field, value); } = true;
 80
 81    /// <summary>
 82    /// Determines whether the workspace can be refreshed.
 83    /// </summary>
 84    /// <returns><see langword="true"/> when the workspace can be refreshed; otherwise <see langword="false"/>.</returns
 085    protected virtual bool CanRefresh() => true;
 86
 87    /// <summary>
 88    /// Determines whether the workspace can be reset.
 89    /// </summary>
 90    /// <returns><see langword="true"/> when the workspace can be reset; otherwise <see langword="false"/>.</returns>
 091    protected virtual bool CanReset() => true;
 92
 93    /// <inheritdoc />
 1594    Task ILoadable.LoadAsync(CancellationToken cancellationToken) => LoadAsync(cancellationToken);
 95
 96    /// <summary>
 97    /// Refreshes the workspace content.
 98    /// </summary>
 99    /// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
 100    /// <returns>A task representing the asynchronous operation.</returns>
 101    public Task RefreshAsync(CancellationToken cancellationToken = default)
 6102        => ExecuteSafeAsync(OnRefreshAsync, cancellationToken);
 103
 104    /// <summary>
 105    /// Resets the workspace state and content.
 106    /// </summary>
 107    /// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
 108    /// <returns>A task representing the asynchronous operation.</returns>
 109    public Task ResetAsync(CancellationToken cancellationToken = default)
 9110        => ExecuteSafeAsync(OnResetAsync, cancellationToken);
 111
 112    /// <summary>
 113    /// Performs the asynchronous refresh logic.
 114    /// </summary>
 115    /// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
 116    /// <returns>A task representing the asynchronous operation.</returns>
 3117    protected virtual Task OnRefreshAsync(CancellationToken cancellationToken = default) => OnLoadAsync(cancellationToke
 118
 119    /// <summary>
 120    /// Performs the asynchronous reset logic.
 121    /// </summary>
 122    /// <param name="cancellationToken">A token to monitor for cancellation requests.</param>
 123    /// <returns>A task representing the asynchronous operation.</returns>
 3124    protected virtual Task OnResetAsync(CancellationToken cancellationToken = default) => Task.CompletedTask;
 125
 126    /// <summary>
 127    /// Creates the workspace title for the specified culture.
 128    /// Called from <see cref="ApplyTitle"/> after construction and on culture changes.
 129    /// </summary>
 130    /// <param name="culture">The culture information to use for creating the title.</param>
 131    /// <returns>The title to assign, or <see langword="null"/> to leave <see cref="Title"/> unchanged.</returns>
 114132    protected virtual string? CreateTitle(CultureInfo culture) => null;
 133
 134    /// <inheritdoc/>
 0135    public virtual void OnEvent(CultureChangedEvent e) => ApplyTitle(e.Culture);
 136
 137    /// <summary>
 138    /// Assigns <see cref="Title"/> from <see cref="CreateTitle"/> when the result is not <see langword="null"/>.
 139    /// </summary>
 140    /// <param name="culture">The culture used to build the title.</param>
 141    protected void ApplyTitle(CultureInfo culture)
 142    {
 132143        ArgumentNullException.ThrowIfNull(culture);
 144
 132145        var title = CreateTitle(culture);
 146
 132147        if (title is not null)
 18148            Title = title;
 132149    }
 150
 151    /// <summary>
 152    /// Schedules an initial title assignment using the current culture.
 153    /// </summary>
 154    /// <param name="culture">The culture to use for the initial title assignment.</param>
 155    private void ScheduleInitialTitle(CultureInfo culture)
 156    {
 132157        var sync = SynchronizationContext.Current;
 158
 132159        if (sync is not null)
 160        {
 132161            sync.Post(_ => ApplyTitle(culture), null);
 132162            return;
 163        }
 164
 0165        ThreadPool.QueueUserWorkItem(_ => ApplyTitle(culture));
 0166    }
 167}
 168