¥£$ ДЕУΙГ

自定义Visual Studio调试窗口

    受到园友麒麟文章启发,我研究了一下自定义调试窗口的相关技术,发现很简单,但对调试效率的提高帮助却很大,以前对于复杂数据的调试显示很抓狂,要么不能显示(只显示一个Type信息),要么一层层的点开来看,很是不爽,如果能自定义调试窗口,按我们希望的方式显示数据该多好啊,下面我来详细介绍一下实现方式。

    Step1:新建一个Console Application,添加对Microsoft.VisualStudio.DebuggerVisualizers的引用。

    005001

    Step2:新建一个类,这个类是我们希望它在调试的时候显示自定义调试窗口信息的,以我的代码为例,建立类MyTable备用。

    Step3:新建类MyTableDebuggerVisualizer,该类继承实现DialogDebuggerVisualizer,该抽象类在命名空间Microsoft.VisualStudio.DebuggerVisualizers下,该抽象类只有一个供使用者实现的Show方法,该方法的两个参数分别是IDialogVisualizerService和IVisualizerObjectProvider,前者是用来控制显示Visualizer(窗体等)的,后者是提供调试数据的,另外还提供了替换、传送数据等方法。

    Step4:新建WinForm窗口MyTableDebuggerViewForm,该窗口将用来展示调试数据。MyTableDebuggerVisualizer只是一个接入点,要显示自己的调试窗口只需要使用IDialogVisualizerService提供的ShowDialog方法显示MyTableDebuggerViewForm即可,当然同时把要调试的数据传入。

  1: using Microsoft.VisualStudio.DebuggerVisualizers;
  2: 
  3: namespace CustomDebugger
  4: {
  5:     public class MyTableDebuggerVisualizer : DialogDebuggerVisualizer
  6:     {
  7:         protected override void Show(IDialogVisualizerService windowService,
  8:             IVisualizerObjectProvider objectProvider)
  9:         {
 10:             // TODO: Get the object to display a visualizer for.
 11:             //       Cast the result of objectProvider.GetObject() 
 12:             //       to the type of the object being visualized.
 13:             MyTable myTable = (MyTable)objectProvider.GetObject();
 14:             // TODO: Display your view of the object.
 15:             //       Replace displayForm with your own custom Form or Control.
 16:             MyTableDebuggerViewForm displayForm = new MyTableDebuggerViewForm(myTable);
 17:             windowService.ShowDialog(displayForm);
 18:         }
 19:     }
 20: }

    Step5:把调试窗口信息关联到类MyTable上,使用System.Diagnostics下的DebuggerVisualizer Attribute为MyTable设置可视化组件。

  1: [DebuggerVisualizer(typeof(MyTableDebuggerVisualizer))]
  2: [Serializable]
  3: public class MyTable
  4: {
  5: }

    注意MyTable头上的Serializable Attribute,在进行自定义调试窗口的时候要求该类必须是可序列化的,所以我加上了Serializable,我猜测这应该是必须的,因为从IVisualizerObjectProvider提供的方法中我们发现,除了有GetObject之外还有GetData,而GetData返回的是Stream,这就要求被调试的对象必须是可序列化的。

    为了可以看到效果,我们先在MyTableDebuggerViewForm里加上一些显示代码

  1: public partial class MyTableDebuggerViewForm : Form
  2: {
  3:     public MyTableDebuggerViewForm(MyTable myTable)
  4:     {
  5:         this.Table = myTable;
  6:         InitializeComponent();
  7:     }
  8: 
  9:     public MyTable Table { get; private set; }
 10: 
 11:     private void MyTableDebuggerViewForm_Load(object sender, EventArgs e)
 12:     {
 13:         this.Text = this.Table.ToString();
 14:     }
 15: }

    到这就可以调试了,在Main函数里随便定义一个MyTable然后打个断点,然后调试。

    005002

    看到那个小放大镜了吗?猛击它

    005003

    我们自定义的窗口显示了出来,并且标题是MyTable的类型名,是不是很简单。最后就是根据自己的需要显示被调试的数据就可以了,文章结尾我会提供一个完整的例子供大家参考。最后还有很重要的一点要说明,关于调试。

    调试“调试窗口”(有点饶口)其实跟调试控件的设计器或者调试Visual Studio插件是类似的,有过控件设计器开发经验的朋友应该已经想到如何调试了,这里跟还不清楚如何调试的朋友简单说明一下:

    005004

    在工程的属性页里找到Debug设置,设置工程的Start Action为Start external program,选择Visual Studio的exe文件devenv.exe,保存设置。然后在MyTableDebuggerViewForm的MyTableDebuggerViewForm_Load方法下打好断点,启动调试,这时会打开一个新的Visual Studio,然后在新的IDE中打开同样的项目,与调试控件设计器略有不同的是,这时要在新的IDE中把工程的调试选项改回Start project(否则再调试就又开一个IDE),然后在新的IDE中打好断点(打在MyTable处),调试MyTable,当打开自定义的调试窗口时,第一个IDE的断点就被命中了。

    最后给大家分享一下完整的调试窗口:)

    005005

    是不是跟DataTable的调试窗口很像?希望本文对您有帮助。

    完整代码下载

posted @ 2010-09-01 15:30  devil0153  阅读(4158)  评论(8编辑  收藏  举报