我的编程空间,编程开发者的网络收藏夹
学习永远不晚

如何使用模板Editor ViewPort Adornment实现扩展

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

如何使用模板Editor ViewPort Adornment实现扩展

今天小编给大家分享一下如何使用模板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实现扩展”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网行业资讯频道。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

如何使用模板Editor ViewPort Adornment实现扩展

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何使用模板Editor ViewPort Adornment实现扩展

今天小编给大家分享一下如何使用模板Editor ViewPort Adornment实现扩展的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起
2023-06-17

win10投影仪扩展模式如何使用

这篇“win10投影仪扩展模式如何使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“win10投影仪扩展模式如何使用”文章吧
2023-06-30

如何使用JavaScript实现模板方法模式

模板方法模式是一种行为设计模式,它是指将一个算法的骨架定义在一个操作中,将一些步骤延迟到子类中实现。模板方法使得子类可以在不改变算法结构的情况下重新定义算法的某些步骤。在本文中,我们将介绍如何使用 JavaScript 实现模板方法模式。实现方法在 JavaScript 中,实现模板方法模式需要遵循以下步骤:1. 定义一个基类,该基类将算法的骨架定义在一个操作中。该操作可以是一
2023-05-14

如何使用MySQL的分布式架构实现水平扩展?

如何使用MySQL的分布式架构实现水平扩展?随着互联网应用的高速发展,大量数据的存储和处理成为了系统设计的一个重要问题。在传统的单机MySQL中,随着数据量的增加,单机的存储和处理能力很容易成为瓶颈。为了解决这个问题,我们可以采用MySQL
2023-10-22

如何使用vbs实现一个扩展时间段的dir命令

这篇文章主要介绍了如何使用vbs实现一个扩展时间段的dir命令,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。核心代码set Arg=Wscript.Arguments If
2023-06-08

如何使用Golang技术实现可扩展的分布式系统?

使用 go 构建可扩展的分布式系统可通过以下步骤实现:使用 goroutine 管理并发:通过创建轻量级的并发单元(goroutine)提升系统并发性。使用管道进行跨 goroutine 通信:通过创建缓冲通道(管道)实现 goroutin
如何使用Golang技术实现可扩展的分布式系统?
2024-05-08

如何使用 C++ 函数模板实现参数化类型?

使用 c++++ 函数模板实现参数化类型简介函数模板可以处理不同类型的通用函数。参数化类型使函数模板更进一步,可以接受不同类型的参数。代码示例: 1. 定义函数模板 print_pair(t, u) 处理不同类型对。 2. 在主函数中调
如何使用 C++ 函数模板实现参数化类型?
2024-04-15

Oracle RAC 如何实现高可用性与性能扩展

Oracle RAC(Real Application Clusters)是Oracle数据库的一种高可用性和性能扩展架构,能够将多台服务器组合成一个集群,共享存储和处理能力,从而提高数据库系统的可用性和性能。本文将介绍Oracle RAC
Oracle RAC 如何实现高可用性与性能扩展
2024-03-07

Django模板中如何实现常用的过滤器

这篇文章主要介绍Django模板中如何实现常用的过滤器,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!模版常用过滤器在模版中,有时候需要对一些数据进行处理以后才能使用。一般在Python中我们是通过函数的形式来完成的。
2023-06-15

如何使用python实现展开列表

这篇文章主要为大家展示了“如何使用python实现展开列表”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何使用python实现展开列表”这篇文章吧。展开列表将列表内的所有元素,包括子列表,都展
2023-06-27

如何用Bash编程实现逻辑操作符和shell扩展

这篇文章将为大家详细讲解有关如何用Bash编程实现逻辑操作符和shell扩展,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。逻辑操作符Bash 中有大量的用于不同条件表达式的逻辑操作符。最基本的是 if 控
2023-06-16

如何使用 C++ 函数模板实现函数指针的泛型化?

c++++ 函数模板允许泛化函数指针,支持不同类型参数的函数指针。具体步骤如下:声明带有函数指针的函数模板,其中 t 为模板类型参数。将要泛化的函数指针作为参数传递给模板函数。模板函数返回泛型函数指针。使用 C++ 函数模板实现函数指针的泛
如何使用 C++ 函数模板实现函数指针的泛型化?
2024-04-15

Vue3 使用v-md-editor如何动态上传图片的方法实现

本文主要介绍了Vue3 使用v-md-editor如何动态上传图片,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2022-11-13

PHP扩展开发:如何使用抽象类实现自定义函数的继承?

在 php 扩展中,使用抽象类实现自定义函数继承的方法如下:定义抽象类,指定函数签名和文档;创建子类实现具体函数;在扩展模块注册自定义函数;创建子类支持不同的转换;注册自定义函数供 php 代码调用。在 PHP 扩展中使用抽象类实现自定义函
PHP扩展开发:如何使用抽象类实现自定义函数的继承?
2024-05-15

如何利用 C++ 函数模板实现泛型编程?

泛型编程通过函数模板实现,允许创建通用的代码处理不同类型的数据,无需修改源代码。函数模板的基本语法为:template returntype functionname(t arg1, t arg2, ...),其中 t 为类型参数。通过实
如何利用 C++ 函数模板实现泛型编程?
2024-04-15

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录