VS外掛開發實現簡單的 ViewModel 和 View 之間的切換

fanbal發表於2024-06-17

VS 外掛開發實現簡單的 ViewModel 和 View 之間的切換

1. 前言

我們在前面一篇中有介紹如何開啟檔案,如果和 ViewModel 與 View 的切換這個場景結合,那麼我們也完全有能力寫出一段程式碼來解決。

2. 程式碼目標

進行 *ViewModel.cs 和 *View.xaml 之間的切換。

3. 可以預見的缺陷

我們僅僅按照檔名進行區分,必不可少地會出現無法對應的問題,整個的專案的結構需要非常死板的遵循。

4. VCmd 程式碼

標題:MVVM 切換


using EnvDTE;
using System;
using System.Collections;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class C : VisualCommanderExt.ICommand
{

        static string[] _viewEndNameArray = new string[] { "View.xaml", "View.axaml", "UserControl.xaml", "UserControl.axaml", "Page.xaml", "Page.axaml" };
        static string[] _viewCsEndNameArray = new string[] {"View.xaml.cs", "View.axaml.cs", "UserControl.xaml.cs", "UserControl.axaml.cs", "Page.xaml.cs", "Page.axaml.cs" };
        static string[] _viewNameArray = new string[] { "UserControl", "Page", "View" };
        static string[] _viewEndExtensionArray = new string[] { ".xaml", ".axaml" };

 public enum FileType
 {
            Unknown, View, ViewModel, ViewCS,
 }

	public void Run(EnvDTE80.DTE2 DTE, Microsoft.VisualStudio.Shell.Package package)
	{
   var projectItem = DTE.ActiveDocument.ProjectItem;

  var projectPath = projectItem.ContainingProject.FullName;
  var projectDir = Path.GetDirectoryName(projectPath);

  var itemPath = projectItem.FileNames[0];

  var relPath = itemPath.Substring(projectDir.Length);

  var fileType = GetFileType(relPath);
  var convertPath = GetConvertFilePath(fileType, relPath, projectDir);

  if (string.IsNullOrWhiteSpace(relPath)) return;

  var fullPath = projectDir + convertPath;

  if (File.Exists(fullPath))
  {
      DTE.Documents.Open(fullPath);
  }
	}
    static FileType GetFileType(string relPath)
   {
       if (_viewEndNameArray.Any(i => relPath.EndsWith(i, StringComparison.OrdinalIgnoreCase))) return FileType.View;
       if (_viewCsEndNameArray.Any(i => relPath.EndsWith(i, StringComparison.OrdinalIgnoreCase))) return FileType.ViewCS;
       if (relPath.EndsWith("ViewModel.cs", StringComparison.OrdinalIgnoreCase)) return FileType.ViewModel;

       return FileType.Unknown;
   }

   static string GetConvertFilePath(FileType fileType, string relPath, string projectDir)
   {
       var result = string.Empty;
       switch (fileType)
       {
           case FileType.View:
               result = relPath;
               foreach (var item in _viewNameArray)
               {
                   result = result.Replace(item, "ViewModel");
               }
               result = result.Replace(".xaml", ".cs").Replace(".axaml", ".cs");
               break;
           case FileType.ViewModel:
               result = relPath;

               foreach (var viewName in _viewNameArray)
               {

                   result = string.Empty;
                   foreach (var ext in _viewEndExtensionArray)
                   {
                       result = relPath.Replace("ViewModel", viewName).Replace(".cs", ext);
                       var fullPath = projectDir + result;
                       if (File.Exists(fullPath)) break;

                       result = string.Empty;
                   }

                   if (string.IsNullOrWhiteSpace(result) == false) break;
               }
               break;
           case FileType.ViewCS:
               result = relPath;
               foreach (var item in _viewNameArray)
               {
                   result = result.Replace(item, "ViewModel");
               }
               result = result.Replace(".xaml.cs", ".cs").Replace(".axaml.cs", ".cs");
               break;
           default:
               break;
       }

       return result;
   }

}

相關文章