国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

VS2013Xml文件節點導航插件開發

2019-11-17 02:45:20
字體:
來源:轉載
供稿:網友

VS2013xml文件節點導航插件開發

一、功能描述

該插件的功能跟代碼文件的導航功能類似,只是下拉框里的內容是元素的某一屬性值,如圖-1所示

圖-1

當點擊下拉框的選項后,會自動定位到該內容在xml文件的位置。此功能適用于xml文件內容較多的情況。

二、選擇Editor Margin插件模板

因為該插件模板會在編輯區的底部創建一個WPF控件,如圖-2所示。

圖-2

而你可以創建一個WPF用戶控件,并將用戶控件添加到該控件里,還可以改變該控件在編輯區的位置。按照Editor Margin模板的向導建立插件項目,在項目里有三個文件:source.extension.vsixmanifest、EditorMargin1、EditorMargin1Factory,改變位置是通過EditorMargin1Factory類的MarginContainerAttribute特性實現的,該特性接收PRedefinedMarginNames靜態類的常量字段,這些常量字段定義了控件可以停靠的位置,如圖-3所示。具體的功能主要是在EditorMargin1文件里實現。

圖-3

當文檔打開的時候VS會加載MarginFactory類的CreateMargin方法執行。

三、創建WPF用戶控件

在項目里添加一個WPF用戶控件,在用戶控件里添加一個ComboBox下拉控件,當下拉框的選項改變的時候觸發定位操作。由于我們是在用戶控件里添加下拉控件,在用戶控件外部無法監控到下拉框的改變事件,所以我們需要在用戶控件里添加一個事件,在下拉框改變事件里觸發該事件,這樣就可以間接訂閱下拉框的選項改變事件。此外,還需要對外開放一個改變下拉框寬度的函數,用于編輯區大小改變的時候可以修改下拉框的寬度。具體的代碼如下所示:

/// <summary>/// MappingInfo.xaml 的交互邏輯/// </summary>public partial class MappingInfo : UserControl{  public delegate void DelegateSelectionChanged(object sender, SelectionChangedEventArgs e);  public event DelegateSelectionChanged SelectionChanged;  public MappingInfo()  {    InitializeComponent();  }  public MappingInfo(IEnumerable<XElement> elements)   {    InitializeComponent();    List<Elements> list = new List<Elements>();    foreach (var item in elements)    {      if (item.Attribute("name") == null)        continue;      Elements model = new Elements();      model.Value = item.Attribute("name").Value;      string desc = item.Attribute("title") != null ? item.Attribute("title").Value : item.Attribute("remark") == null ? "" : item.Attribute("remark").Value;      string cache = item.Attribute("cache") != null ? item.Attribute("cache").Value : "";      model.Text = desc != "" ? string.Format("{0}({1})", model.Value, desc) : model.Value;      if (cache != "" && cache.Equals("true", StringComparison.OrdinalIgnoreCase))      {        model.Text += " √";      }      list.Add(model);    }    cbElement.DisplayMemberPath = "Text";    cbElement.SelectedValuePath = "Value";    cbElement.ItemsSource = list;    cbElement.SelectedIndex = 0;    //訂閱選項改變時的事件    cbElement.SelectionChanged += cbElement_SelectionChanged;  }  void cbElement_SelectionChanged(object sender, SelectionChangedEventArgs e)  {    SelectionChanged(sender, e);  }  public void SetComboBoxWidth(double width)   {    this.cbElement.Width = width;  }}class Elements{  public string Text { get; set; }  public string Value { get; set; }}

在EditorMargin1類的構造函數里將自定義的wpf用戶控件添加到插件創建的控件里

//設置導航欄的相關信息this.Height = 25;this.ClipToBounds = false;this.Background = new SolidColorBrush(Colors.WhiteSmoke);this.Children.Add(mapInfo);//導航欄大小改變時改變下拉框的寬度this.SizeChanged += Navigate_SizeChanged;

四、使用戶控件自適應編輯區寬度

要實現自適應的功能只需要在XmlFileNavigation類的構造函數里訂閱SizeChanged事件,由于EditorMargin1類繼承了Canvas類,而Canvas類又從其他類繼承了SizeChanged事件,所以只要通過this.SizeChanged就可以訂閱該事件,在事件里調用創建的用戶控件對外開發的修改寬度函數即可。代碼如下所示:

/// <summary>/// 大小改變時下拉框也一起調整/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void Navigate_SizeChanged(object sender, SizeChangedEventArgs e){  //調整下拉框大小  //mapinfo為添加的wpf用戶控件  mapInfo.SetComboBoxWidth(((EditorMargin1)sender).ActualWidth); }

為什么要在SizeChanged事件里設置下拉框的寬度,在EditorMargin1類的構造函數里設置就不行嗎?因為在構造函數里獲取編輯區寬度的話,第一個頁面獲取的寬度是不準確的,獲取的寬度都是800,之后打開的頁面的寬度才是正常的。有興趣的同學可以在EditorMargin1類的構造函數里添加如下的代碼,獲取文檔的寬度驗證一下

EnvDTE.DTE dte=ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;double width = dte.ActiveDocument.ActiveWindow.Width;

五、根據選中的內容進行定位

由于該插件是針對xml文件的,而VS沒有提供對xml文件內容的定位方法(可能是我還不知道),所以只能通過遍歷整個文件來確定選中的內容是在文件中的行數。以下是在用戶控件的響應事件里對選中的內容進行定位的代碼:

/// <summary>/// 下拉框改變事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>void cb_SelectionChanged(object sender, SelectionChangedEventArgs e){  try  {    //獲取下拉框選中項    Elements model = (Elements)((ComboBox)sender).SelectedItem;    //獲取DTE實例    DTE dte = ServiceProvider.GlobalProvider.GetService(typeof(DTE)) as DTE;    //找出選中項在xml文件里的行數    string[] lines = File.ReadAllLines(dte.ActiveDocument.FullName);    int line = 0;    foreach (var item in lines)    {      line++;      if (item != "" && item.Contains(model.Value))      {        break;      }    }    //滾動條滾動到指定行數并顯示光標    TextSelection selection = dte.ActiveDocument.Selection as TextSelection;    if (selection != null)    {      selection.MoveToLineAndOffset(line, 3);      selection.ActivePoint.TryToShow();    }  }  catch (Exception ex)  {    MessageBox.Show(ex.Message, "提示", MessageBoxButton.OK, MessageBoxImage.Error);  }}

如果要開發的導航插件式針對cs文件的話可以通過下面的代碼獲取cs文件里的字段、函數、事件、屬性等的相關信息:

dte.ActiveDocument.ProjectItem.FileCodeModel

以下的代碼是針對ComboBox的美化樣式

  1 <UserControl.Resources>  2         <ControlTemplate x:Key="ComboBoxToggleButton" TargetType="{x:Type ToggleButton}">  3             <Grid>  4                 <Grid.ColumnDefinitions>  5                     <ColumnDefinition />  6                     <ColumnDefinition Width="15" />  7                 </Grid.ColumnDefinitions>  8                 <Border  9   x:Name="Border"  10   Grid.ColumnSpan="2" 11   CornerRadius="0" 12   Background="#FCFCFC" 13   BorderBrush="#9BA7B7" 14   BorderThickness="1 1 1 1" /> 15                 <Border  16   Grid.Column="0" 17   CornerRadius="0"  18   Margin="1"  19   Background="#FCFCFC"  20   BorderBrush="#9BA7B7" 21   BorderThickness="0" /> 22                 <Path  23   x:Name="Arrow" 24   Grid.Column="1"      25   Fill="Black" 26   HorizontalAlignment="Center" 27   VerticalAlignment="Center" 28   Data="M 0 0 L 4 4 L 8 0 Z"/> 29             </Grid> 30             <ControlTemplate.Triggers> 31                 <Trigger Property="ToggleButton.IsMouSEOver" Value="true"> 32                     <Setter TargetName="Border" Property="Background" Value="#FDF4BF" /> 33                     <Setter TargetName="Border" Property="BorderBrush" Value="#FFEC8B" /> 34                 </Trigger> 35                 <Trigger Property="ToggleButton.IsChecked" Value="true"> 36                     <Setter TargetName="Border" Property="Background" Value="#FFEC8B" /> 37                 </Trigger> 38                 <Trigger Property="IsEnabled" Value="False"> 39                     <Setter TargetName="Border" Property="Background" Value="#EEEEEE" /> 40                     <Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" /> 41                     <Setter Property="Foreground" Value="#888888"/> 42                     <Setter TargetName="Arrow" Property="Fill" Value="#888888" /> 43                 </Trigger> 44             </ControlTemplate.Triggers>
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 琼结县| 噶尔县| 宜兰市| 苍山县| 庄浪县| 沐川县| 泽库县| 韶山市| 绍兴市| 海淀区| 灵山县| 望奎县| 日土县| 德江县| 东城区| 林周县| 合阳县| 新蔡县| 东阳市| 宝鸡市| 皮山县| 鞍山市| 泽州县| 大埔县| 桐乡市| 德格县| 宣恩县| 定兴县| 西峡县| 繁昌县| 长沙市| 长泰县| 宁阳县| 平果县| 平山县| 洛南县| 同仁县| 鄂伦春自治旗| 仲巴县| 海丰县| 龙山县|