File: MoveToNamespace\MoveToNamespaceDialogViewModel.cs
Web Access
Project: src\src\VisualStudio\Core\Def\Microsoft.VisualStudio.LanguageServices_pxr0p0dn_wpftmp.csproj (Microsoft.VisualStudio.LanguageServices)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
 
using System;
using System.Collections.Immutable;
using System.ComponentModel;
using System.Linq;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.LanguageService;
using Microsoft.VisualStudio.Imaging;
using Microsoft.VisualStudio.Imaging.Interop;
using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities;
 
namespace Microsoft.VisualStudio.LanguageServices.Implementation.MoveToNamespace;
 
internal class MoveToNamespaceDialogViewModel : AbstractNotifyPropertyChanged, IDataErrorInfo
{
    private readonly ISyntaxFacts _syntaxFacts;
 
    public MoveToNamespaceDialogViewModel(
        string defaultNamespace,
        ImmutableArray<string> availableNamespaces,
        ISyntaxFacts syntaxFacts,
        ImmutableArray<string> namespaceHistory)
    {
        _syntaxFacts = syntaxFacts ?? throw new ArgumentNullException(nameof(syntaxFacts));
        _namespaceName = defaultNamespace;
        AvailableNamespaces = namespaceHistory.Select(n => new NamespaceItem(true, n))
            .Concat(availableNamespaces.Except(namespaceHistory).Select(n => new NamespaceItem(false, n)))
            .ToImmutableArray();
 
        PropertyChanged += MoveToNamespaceDialogViewModel_PropertyChanged;
    }
 
    private void MoveToNamespaceDialogViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        switch (e.PropertyName)
        {
            case nameof(NamespaceName):
                OnNamespaceUpdated();
                break;
        }
    }
 
    public void OnNamespaceUpdated()
    {
        var isNewNamespace = !AvailableNamespaces.Any(static (i, self) => i.Namespace == self.NamespaceName, this);
        var isValidName = !isNewNamespace || IsValidNamespace(NamespaceName);
 
        if (isNewNamespace && isValidName)
        {
            Icon = KnownMonikers.StatusInformation;
            Message = ServicesVSResources.A_new_namespace_will_be_created;
            ShowMessage = true;
            CanSubmit = true;
        }
        else if (!isValidName)
        {
            Icon = KnownMonikers.StatusInvalid;
            Message = ServicesVSResources.This_is_an_invalid_namespace;
            ShowMessage = true;
            CanSubmit = false;
        }
        else
        {
            ShowMessage = false;
            CanSubmit = true;
        }
    }
 
    private bool IsValidNamespace(string namespaceName)
    {
        if (string.IsNullOrEmpty(namespaceName))
        {
            return false;
        }
 
        foreach (var identifier in namespaceName.Split('.'))
        {
            if (_syntaxFacts.IsValidIdentifier(identifier))
            {
                continue;
            }
 
            return false;
        }
 
        return true;
    }
 
    private string _namespaceName;
    public string NamespaceName
    {
        get => _namespaceName;
        set => SetProperty(ref _namespaceName, value);
    }
 
    public ImmutableArray<NamespaceItem> AvailableNamespaces { get; }
 
    private ImageMoniker _icon;
    public ImageMoniker Icon
    {
        get => _icon;
        private set => SetProperty(ref _icon, value);
    }
 
    private string? _message;
    public string? Message
    {
        get => _message;
        private set => SetProperty(ref _message, value);
    }
 
    private bool _showMessage = false;
    public bool ShowMessage
    {
        get => _showMessage;
        private set => SetProperty(ref _showMessage, value);
    }
 
    private bool _canSubmit = true;
    public bool CanSubmit
    {
        get => _canSubmit;
        private set => SetProperty(ref _canSubmit, value);
    }
 
    public string Error => CanSubmit ? string.Empty : Message ?? string.Empty;
 
    public string this[string columnName]
        => columnName switch
        {
            nameof(NamespaceName) => Error,
            _ => string.Empty
        };
 
}