一种以图形方式显示VS调试器中当前执行状态的方法

时间:2013-11-16 17:31:26

标签: c# visual-studio debugging

我有一个我想要调试的树结构,它只包含节点,因此在调试器中跟踪它是非常麻烦的。我正在寻找一种让我生成当前状态图的方法,最好是根据我的喜好进行配置,以便我可以快速观察我的树在任何给定断点上的外观。

是否有这样的工具已经可用或我是否被迫实施我的图表绘制?

1 个答案:

答案 0 :(得分:3)

您有几个选择。最简单的(但仍然是基于文本的)是编写一个自定义类,以更易于阅读的格式显示信息,并使用树类的[DebuggerTypeProxy]属性使其使用新的自定义调试器类型类在查看一个自定义树类时,可以控制调试器的文本显示中显示的内容。

第二个选项(如果你想做一个花哨的图形用户界面会很复杂)就是创建一个Visualizer。这将允许您设计和创建一个可以显示您想要的任何内容的新窗口,但是您必须将可视化器“安装”到visual studio中才能工作(通过将程序集复制到My Documents\VisualStudioVersion\Visualizers)。通过足够的工作,您可以创建一个可视化工具,让您可以单击调试器中某个树对象上的可视化器图标,并让它打开一个看起来像Parallel Stacks Window一样华丽的新窗口并拥有该窗口以图形形式显示树对象。


以下是使用TreeView控件显示数据的可视化工具的基本示例。

using System.Diagnostics;
using Microsoft.VisualStudio.DebuggerVisualizers;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace StackOverflowExample
{
    public interface ITreeData
    {
        ITreeDataNode Top { get; }
    }

    public interface ITreeDataNode
    {
        string Data { get; set; }
        List<ITreeDataNode> Children { get; }
    }

    /// <summary>
    /// A Visualizer for TreeData.  
    /// </summary>
    public class TreeDataVisualizer : DialogDebuggerVisualizer
    {
        protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
        {
            if (windowService == null)
                throw new ArgumentNullException("windowService");
            if (objectProvider == null)
                throw new ArgumentNullException("objectProvider");

            var treeData = (ITreeData)objectProvider.GetObject();

            using (var treeView = new TreeView())
            {
                treeView.AutoSize = true;
                treeView.Dock = DockStyle.Fill;

                var topNode = treeView.Nodes.Add(treeData.Top.Data);

                //Recursively populate all of the child nodes.
                PopulateNodes(topNode, treeData.Top);

                windowService.ShowDialog(treeView);
            }
        }

        private static void PopulateNodes(TreeNode node, ITreeDataNode treeDataNode)
        {
            foreach (var childNode in treeDataNode.Children)
            {
                var newNode = node.Nodes.Add(childNode.Data);
                PopulateNodes(newNode, childNode);
            }
        }
    }
}

将上述内容构建为类库并将其放入My Documents\VisualStudioVersion\Visualizers

然后在第二个控制台应用程序中添加对您创建的DLL的引用,并键入以下

using System;
using System.Collections.Generic;
using System.Diagnostics;
using StackOverflowExample;

namespace ConsoleApplication1
{
    [DebuggerVisualizer(typeof(TreeDataVisualizer))]
    [Serializable]
    public class TreeData : ITreeData
    {
        public TreeData(string topData)
        {
            Top = new TreeDataNode(topData);
        }

        public ITreeDataNode Top { get; private set; }
    }

    [Serializable]
    public class TreeDataNode : ITreeDataNode
    {
        public TreeDataNode(string data)
        {
            Data = data;
            Children = new List<ITreeDataNode>();
        }

        public string Data { get; set; }
        public List<ITreeDataNode> Children { get; private set; }
    }

    internal class Program
    {
        private static void Main(string[] args)
        {
            var data = new TreeData("Top Node");
            data.Top.Children.Add(new TreeDataNode("1a"));

            var middleChild = new TreeDataNode("1b");
            data.Top.Children.Add(middleChild);

            data.Top.Children.Add(new TreeDataNode("1c"));

            middleChild.Children.Add(new TreeDataNode("2a"));
            middleChild.Children.Add(new TreeDataNode("2b"));

            Debugger.Break();
        }
    }
}

当调试器中断时,您应该在data的监视列表中看到magnifying glass icon,当您单击它时Visual Studio将打开一个带有我们创建的控件的新窗口。

enter image description here