插件監(jiān)控一個(gè)xml文件,當(dāng)該文檔有添加新元素在保存的時(shí)候?qū)⑿略龅脑赝降街付ǖ哪夸浵隆?/p>
由于該功能是跟代碼編輯有關(guān)的,要監(jiān)控文檔的保存事件,所以要在文檔打開的時(shí)候就注冊(cè)保存事件的響應(yīng)方法。VS提供了一個(gè)接口,監(jiān)聽文檔的打開事件,這個(gè)接口就是:IWpfTextViewCreationListener,接口代碼如下,該接口只有一個(gè)方法,在文檔打開的時(shí)候會(huì)調(diào)用TextViewCreated方法執(zhí)行。
// 摘要: // Listens to text view created events.public interface IWpfTextViewCreationListener{ // 摘要: // Called when a text view having matching roles is created over a text data // model having a matching content type. // // 參數(shù): // textView: // The newly created text view. void TextViewCreated(IWpfTextView textView);}所以隨便選擇一個(gè)模板都是可以的,只要在項(xiàng)目里面將模板創(chuàng)建的插件入口類改為繼承IWpfTextViewCreationListener接口,并實(shí)現(xiàn)其接口即可。由于該功能需要用到選項(xiàng)配置功能,所以我建議讀者使用Visual Stuido Package模板,因?yàn)槭褂迷撃0逄砑舆x項(xiàng)頁會(huì)比較容易。這是msdn上在使用Visual Studio Package模板的情況下如何添加選項(xiàng)頁的教程:http://msdn.microsoft.com/en-us/library/bb166195.aspx。我選擇的是Editor Text Adornment模板,因?yàn)樵撃0鍎?chuàng)建的入口類就是繼承IWpfTextViewCreationListener接口,但是使用該模板的話,添加選項(xiàng)頁會(huì)比較麻煩一點(diǎn)。
按照msdn上的教程,我們知道需要添加兩個(gè)類:繼承Package的類和繼承DialogPage的類,過程我就不再贅述。如果緊緊按照msdn上的教程,你會(huì)發(fā)現(xiàn)在工具-選項(xiàng)下根本沒有我們添加的選項(xiàng)頁(非Visual Studio Package模板的情況),這是為什么呢?原來在我們的csPRoj文件和source.extension.vsixmanifest里缺少了一些元素,按照下面的步驟就可以實(shí)現(xiàn)添加選項(xiàng)頁的功能:
1、打開source.extension.vsixmanifest,選擇Assets選項(xiàng),點(diǎn)擊New按鈕,彈出圖-1窗口

圖-1
Type選擇Microsoft.VisualStudio.Assembly,Source選擇A project in current solution,Project選擇當(dāng)前的插件項(xiàng)目,點(diǎn)擊OK添加完成,再次點(diǎn)擊New按鈕,這次的Type選擇Microsoft.VisualStudio.VsPackage,Source和Project跟第一次的一樣即可。
2、將csproj文件里的GeneratePkgDefFile元素改為true。
3、GeneratePkgDefFile元素后添加<CopyBuildOutputToOutputDirectory>true</CopyBuildOutputToOutputDirectory>
4、在GeneratePkgDefFile元素前添加<IncludeAssemblyInVSIXContainer>true</IncludeAssemblyInVSIXContainer>,注意IncludeAssemblyInVSIXContainer這個(gè)元素一定要添加在GeneratePkgDefFile和CopyBuildOutputToOutputDirectory元素之前。
經(jīng)過上面的四個(gè)步驟,我們添加的選項(xiàng)頁就會(huì)顯示在工具-選項(xiàng)里了,如果缺少了第一個(gè)步驟的話會(huì)出現(xiàn)”加載此屬性頁時(shí)出錯(cuò)“的錯(cuò)誤。
通過查看TextViewCreated函數(shù)的參數(shù)類型textView,可以知道IWpfTextView接口并沒有包含文檔保存的事件。那么,我們?cè)撊绾尾拍苡嗛啽4媸录兀客ㄟ^查找相關(guān)的資料,發(fā)現(xiàn)可以通過以下方式獲取文檔的保存事件:
//EnvDTE.DTE _dtethis._dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;//EnvDTE.Events _eventsthis._events = this._dte.Events;//EnvDTE.DocumentEvents _docEventsthis._docEvents = this._events.DocumentEvents;
一定要記住一定要將上面的三個(gè)對(duì)象定義為全局變量,否則就沒辦法響應(yīng)保存事件,這是因?yàn)镃#的垃圾回收機(jī)制造成的,讀者可以自己試一下定義為局部變量的情況。
以下是該插件的部分代碼

1 namespace AppSettingsSync 2 { 3 public class TextViewListener 4 { 5 /// <summary> 6 /// 文檔信息 7 /// </summary> 8 private ITextView _view; 9 10 private DTE _dte; 11 private Events _events; 12 private DocumentEvents _docEvents; 13 /// <summary> 14 /// 文檔是否修改過 15 /// </summary> 16 private bool _isChanged; 17 /// <summary> 18 /// 保存的時(shí)候是否自動(dòng)同步到其他AppSettings.xml 19 /// </summary> 20 private bool _isAutoReplace = true; 21 /// <summary> 22 /// 觸發(fā)同步操作的AppSetting.xml 23 /// </summary> 24 private string _sourceFile; 25 /// <summary> 26 /// 要被同步的AppSettings.xml所在的文件目錄 27 /// </summary> 28 private string _targetFolder; 29 30 /// <summary> 31 /// 打開文檔時(shí)觸發(fā) 32 /// </summary> 33 /// <param name="textView"></param> 34 public TextViewListener(IWpfTextView textView) 35 { 36 this._view = textView; 37 this._dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE; 38 Properties props = this._dte.get_Properties("IStrong", "AppSettingsSync"); 39 if (props == null) 40 return; 41 this._sourceFile = (string)props.Item("SourceXmlFilePath").Value; 42 //File.AppendAllText(@"D:/log.txt", "源文件" + this._sourceFile + "當(dāng)前文件" + this._dte.ActiveDocument.FullName); 43 if (!this._dte.ActiveDocument.FullName.Equals(this._sourceFile, StringComparison.OrdinalIgnoreCase)) 44 return; 45 //獲取DTE對(duì)象 46 this._events = this._dte.Events; 47 this._docEvents = this._events.DocumentEvents; 48 //訂閱文檔保存和修改事件 49 this._docEvents.DocumentSaved += _docEvents_DocumentSaved; 50 this._view.TextBuffer.Changed += TextBuffer_Changed; 51 } 52 53 /// <summary> 54 /// 文檔修改事件 55 /// </summary> 56 /// <param name="sender"></param> 57 /// <param name="e"></param> 58 void TextBuffer_Changed(object sender, Microsoft.VisualStudio.Text.TextContentChangedEventArgs e) 59 { 60 if (e.Changes.Count() > 0) 61 this._isChanged = true; 62 } 63 64 /// <summary> 65 /// 文檔保存事件 66 /// </summary> 67 /// <param name="Document"></param> 68 async void _docEvents_DocumentSaved(Document Document) 69 { 70 try 71 { 72 //File.AppendAllText(@"D:/log.txt", "觸發(fā)保存事件"); 73 //獲取Tool->Opetions->IStrong->AppSettingsSync配置項(xiàng)內(nèi)容 74 Properties props = this._dte.get_Properties("IStrong", "AppSettingsSync"); 75 if (props == null) 76 return; 77 this._sourceFile = (string)props.Item("SourceXmlFilePath").Value; 78 //保存時(shí)要同時(shí)滿足是源AppSettings.xml文件和該文件有被修改過 79 if (Document.FullName.Equals(this._sourceFile, StringComparison.OrdinalIgnoreCase) && this._isChanged) 80 { 81 this._isAutoReplace = (bool)props.Item("IsAutoSync").Value; 82 this._targetFolder = (string)props.Item("TargetFolder").Value; 83 //手動(dòng)選擇要同步的文件 84 if (!this._isAutoReplace) 85 { 86 SelectFiles sf = new SelectFiles(this._sourceFile, this._targetFolder); 87 sf.ShowDialog(); 88 this._isChanged = false; 89 } 90 else 91 { 92 //自動(dòng)同步文件 93 string fileName = System.IO.Path.GetFileName(this._sourceFile); 94 string[] files = Directory.GetFiles(this._targetFolder, fileName, SearchOption.AllDirectories); 95 this._isChanged = false; 96 await SyncHelper.SyncAppSettings(this._sourceFile, files); 97 //同步完成后修改Visual Studio狀態(tài)欄信息 98 IVsStatusbar bar = ServiceProvider.GlobalProvider.GetService(typeof(SVsStatusbar)) as IVsStatusbar; 99 bar.SetText("AppSettings配置文件同步完成。");100 }101 }102 }103 catch (Exception ex)104 {105 MessageBox.Show(ex.Message, "提示", MessageBoxButton.OK, MessageBoxImage.Error);106 }107 }108 }109 }View Code獲取VS的主題顏色
/// <summary>/// 將模態(tài)窗口的顏色設(shè)置為Visual Studio的背景色/// </summary>/// <param name="themeColor"></param>/// <returns></returns>private Color converVsThemeColor(vsThemeColors themeColor){ DTE2 dte2 = (EnvDTE80.DTE2)S
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注