我有一个我想要调试的树结构,它只包含节点,因此在调试器中跟踪它是非常麻烦的。我正在寻找一种让我生成当前状态图的方法,最好是根据我的喜好进行配置,以便我可以快速观察我的树在任何给定断点上的外观。
是否有这样的工具已经可用或我是否被迫实施我的图表绘制?
答案 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
的监视列表中看到,当您单击它时Visual Studio将打开一个带有我们创建的控件的新窗口。