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;
}
}