中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何使用模板Editor ViewPort Adornment實現擴展

發布時間:2022-03-31 14:19:41 來源:億速云 閱讀:171 作者:iii 欄目:編程語言

今天小編給大家分享一下如何使用模板Editor ViewPort Adornment實現擴展的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

第一步:創建一個Viewport Adornment項目

我們從Extensibility中選擇Viewport Adornment模板創建一個項目。這將生成一個SourceManifest文件和兩個類文件。一個是Adornment類本身,另外一個是AdornmentFactory類。

第二步:添加一個WPF用戶控件

右鍵單擊項目,選擇添加一個新的WPF用戶控件。為了簡單起見,我使用了一個用戶控件。這個用戶控件實際上包含一個Expander控件,設置它的ExpandDirection = Left,它里面又包含了一些TextBlock控件和另外一個Expander ,設置里面的這個Expander的ExpandDirection = Down。看下面的代碼(我刪除不必要的元素,使其更簡單):

<Expander ExpandDirection="Left" Style="{DynamicResource ExpanderStyle1}"   x:Name="expMain" > <StackPanel> <TextBlock x:Name="txtNoLines"   Text="No of Lines : {0}"   Margin="25 25 25 0"   FontSize="12"   FontFamily="Verdana"   FontWeight="Bold"   Foreground="Yellow"></TextBlock> <TextBlock x:Name="txtNoCharacters"   Text="No of Characters : {0}"   Margin="25 5 25 15"   FontSize="12"   FontFamily="Verdana"   FontWeight="Bold"   Foreground="Yellow"></TextBlock> <Expander x:Name="expCodeInfo" ExpandDirection="Down"   Header="Code Information"> <StackPanel> <TextBlock x:Name="txtClassInfo"   Margin="25 25 25 0"   FontSize="12"   FontFamily="Verdana"   FontWeight="Bold"   Foreground="LightYellow"/> <Line Margin="0,4" SnapsToDevicePixels="True" Stroke="Gold" Stretch="Fill" X1="0" X2="1"   /> <TextBlock x:Name="txtFileSize" Margin="25 5 25 15"   FontSize="12"   FontFamily="Verdana"   FontWeight="Bold"   Foreground="AliceBlue"/> </StackPanel> </Expander> </StackPanel> </Expander>

你可以看到,代碼很簡單,兩個Expanders,一個用來顯示基本的統計信息和另外一個顯示擴展的統計信息。我還使用StackPanel來固定TextBlocks布局。現在,如果你看一下后臺代碼,發現它也一樣簡單。其實我已經創建了一個CodeInfoTracker類,用它來為我們分析源代碼文件。我只是為我們的用戶控件添加了一個構造函數,使用戶控件更具擴展性而已。

private CodeInfoTracker _cinfo;  private CodeInfoTracker.Calculators _calculator;  public ucInfoBox(CodeInfoTracker cinfo)  : this()   {  this._cinfo = cinfo;  }  public void UpdateInfo(CodeInfoTracker info)  {  _calculator = info.PerFormCalculate();  this.txtNoLines.Text = string.Format("No of Lines : {0}",   _calculator.no_of_lines);  this.txtNoCharacters.Text = string.Format("No of Characters : {0}",   _calculator.no_of_characters);  this.txtFileSize.Text = string.Format("Total File Size : {0}",   _calculator.totalfilesize);   StringBuilder builder = new StringBuilder();  if (this._calculator.interfaces != 0)  builder.AppendFormat("Interfaces : {0}\n\r",   this._calculator.interfaces);  if (this._calculator.namespaces != 0)  builder.AppendFormat("NameSpaces : {0}\n\r",   this._calculator.namespaces);  if (this._calculator.classes != 0)  builder.AppendFormat("Classes : {0}\n\r",   this._calculator.classes);  if (this._calculator.methods != 0)  builder.AppendFormat("Methods : {0}\n\r", this._calculator.methods);  if (this._calculator.properties != 0)  builder.AppendFormat("Properties : {0}\n\r",   this._calculator.properties);  if (this._calculator.fields != 0)  builder.AppendFormat("Fields : {0}\n\r", this._calculator.fields);  if (this._calculator.comments != 0)  builder.AppendFormat("Comments : {0}\n\r", this._calculator.comments);  if (builder.Length > 0)  {  this.txtClassInfo.Visibility = System.Windows.Visibility.Visible;  this.txtClassInfo.Text = builder.ToString();  }  else  {  this.txtClassInfo.Text = "";  this.txtClassInfo.Visibility = System.Windows.Visibility.Hidden;  }  }

使用了一個結構體Calculators ,這個結構體放置在我們的自定義類中,它有幾個int屬性用來保存分析源文件獲取的所有信息。 info.PerFormCalculate(); 給出分析的結果。這里使用的所有獲取的信息來更新了UIElements。

第三步:創建獲取源文件信息的類

雖然代碼存在一些復雜性,但是這個類其實很簡單。我很感謝CS Parser [^],它幫助我自動地解析源代碼。這個類需要一個IWpfTextView對象,它代表著Visual Studio 2010文本編輯器。實際上WpfTextView實現了IWpfTextView。在執行期間這個類接受這個對象。

我可以從WPFTextView.TextSnapshot.GetText()獲得到了源代碼。在我調用的這個分析的時候,我只需要檢測的代碼是什么語言寫的。開始我想自己來實現,但是感謝上帝,我在WPFTextView中發現已經存在這個對象了。

public enum Language  {  CSharp, VisualBasic, Indeterminate  }  internal Language DetectLanguage  {  get  {  string langtype =   this._view.FormattedLineSource.TextAndAdornmentSequencer.  SourceBuffer.ContentType.DisplayName;  if(langtype.Equals("CSHARP",   StringComparison.InvariantCultureIgnoreCase))  return Language.CSharp;  else if(langtype.Equals("BASIC",   StringComparison.InvariantCultureIgnoreCase))  return Language.VisualBasic;  else  return Language.Indeterminate;  }  }

DetectLanguage妥善地利用WPFTextView對象的FormattedLineSource.TextAndAdornmentSequencer。SourceBuffer.ContentType.DisplayName,這個屬性告訴我是使用了哪種語言。之后我創建了一個新的方法PerFormCalculate,用它來解析源代碼,它返回一個Calculation結構對象。

第四步:創建 Adornment Factory 類

回到這個擴展,我創建一個Adornment(InfoBoxAdornmentFactory)的Factory類。這個類繼承IWpfTextViewCreationListener,用來監聽WPF的編輯和創建事件。

[Export(typeof(IWpfTextViewCreationListener))]  [ContentType("text")]  [TextViewRole(PredefinedTextViewRoles.Document)]   internal sealed class InfoBoxAdornmentFactory : IWpfTextViewCreationListener  {  [Export(typeof(AdornmentLayerDefinition))]  [Name("AlwaysVisibleInfoBox")]  [Order(After = PredefinedAdornmentLayers.Selection)]  [TextViewRole(PredefinedTextViewRoles.Interactive)]  public AdornmentLayerDefinition editorAdornmentLayer = null;  public void TextViewCreated(IWpfTextView textView)  {  new AlwaysVisibleInfoBox(textView);  }  }

這里,你可以看到我在這個類上使用了很多Attributes,像ContentType,它定義了我們只處理文本格式的編輯器;還有TextViewRole,它定義了將被這個類處理的textview的類型。在這個類中,我創建了一個AdornmentLayerDefination對象。可能你想知道我們沒有使用它,無什么還需要定義它呢,它只是用來配置屬性的。Order屬性指定,當,InfoBox在層被選之后監聽,Name是編輯擴展的名字。

第五步:創建Adornment 類

Adornment類實際創建了一個WPF用戶控件對象,并設置它的視圖畫布。在內部構造函數中,我處理IWpfTextView.LayoutChanged事件,當代碼修改或者布局改變的時候,就觸發這個事件。

因此,通過這一事件,當我們編輯的文檔時,我們可以很容易地得到回調。當瀏覽器編輯器的大小改變時,我還通過處理WPFTextView.ViewportHeightChanged,WPFTextView.ViewportWidthChanged得到回調,使我們可以重新定位相應的UserControl。

public AlwaysVisibleInfoBox(IWpfTextView view)  {  _view.LayoutChanged += this.OnLayoutChanged;  this.GetLayer();   }  private void GetLayer()  {   _adornmentLayer = this._view.GetAdornmentLayer("AlwaysVisibleInfoBox");  _view.ViewportHeightChanged += delegate { this.onSizeChange(); };  _view.ViewportWidthChanged += delegate { this.onSizeChange(); };  }  private void OnLayoutChanged(object sender, TextViewLayoutChangedEventArgs e)  {  this._info = new CodeInfoTracker(_view);  this.infobox.UpdateInfo(this._info);  }  public void onSizeChange()  {   _adornmentLayer.RemoveAllAdornments();  Canvas.SetLeft(infobox, _view.ViewportRight - 255);   Canvas.SetTop(infobox, _view.ViewportTop + 10);   _adornmentLayer.AddAdornment(AdornmentPositioningBehavior.ViewportRelative,    null, null,   infobox, null);   }

因此,構造函數只是調用GetLayer來獲取的Layer對象,發生在ViewportHeightChanged和ViewportWidthChanged ViewPortSizeChage事件。當一個布局改變時,我就能更新這個用戶的控件。至此,我們成功地建立我們的擴展。你可以使用F5運行它,它會打開一個Visual Studio 2010的Experimental實例。

安裝和卸載這個擴展:

安裝和卸載這個擴展是非常容易的。當您編譯項目后,它會產生一個VSIX文件。您可以只需雙擊這個文件,它會自動安裝到Visual Studio 2010。

如何使用模板Editor ViewPort Adornment實現擴展

以上就是“如何使用模板Editor ViewPort Adornment實現擴展”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

巴彦县| 贡嘎县| 甘洛县| 调兵山市| 惠水县| 石渠县| 阿合奇县| 贡嘎县| 乐平市| 怀安县| 琼海市| 婺源县| 玛纳斯县| 尉氏县| 徐水县| 思南县| 亳州市| 定日县| 任丘市| 友谊县| 清丰县| 伊吾县| 托克托县| 泌阳县| 谷城县| 贺州市| 隆安县| 梧州市| 安庆市| 淮滨县| 洞头县| 多伦县| 高平市| 三台县| 三门峡市| 新巴尔虎左旗| 焦作市| 广灵县| 谷城县| 时尚| 武汉市|