Click here to Skip to main content
Click here to Skip to main content

Yet Another QuickWatch

, 26 Nov 2007
Rate this:
Please Sign up or sign in to vote.
This QuickWatch displays complex data as a user-friendly tree
Screenshot - snapshot.png

Introduction

Once upon a time, there was a project where testers and advanced users had to have a tool to watch complex data. That's why I made a tool inspired by the Visual Studio QuickWatch.

It has some extra features, in addition:

  • It displays only fields/properties (i.e. members) a developer wants to be seen by users
  • It allows to assign user-friendly names to displayed members
  • It allows to save a selected sub-tree to a file

Builder

A few months ago, I was asked to display data which consists of over twenty classes; each class has about ten different members. It was just too complex to make a one-purpose piece of code to display it. Especially it was almost impossible to maintain it because the data structure changes.

So, how to automate the process? I use attributes to tag members that users should see:

  • TreeLeafNodeAttribute – Defines a member as a tree leaf, it cannot contain any nodes or leafs. Usually used for strings, numbers and dates.
  • TreeInternalNode – Defines a member as an internal tree node, it contains nodes or leafs. Usually used for nested structures and collections.

Example:

public class Catalog
{
    [TreeLeafNode]
    public string name;

    [TreeInternalNode]
    public Source source;

    [TreeInternalNode]
    public List<Cd> cds;
}

Such an object is passed to the builder which is divided into three layers:

  1. A base layer – Implements the logic of building the tree
  2. A middle layer – Renders the tree content to a concrete output device
  3. A top layer – Makes the builder type-safe and handles special cases

The builder walks through all tagged members of a passed object recursively. To get the structure of tagged members, the builder uses the TreeStructure class to extract the structure using System.Reflection. The result is cached in a static hash table because it does not change during the application run. It's re-used in all later builder runs.

The builder distinguishes between two types of internal nodes: collections and others. If the item tagged with the TreeInternalNode attribute implements IEnumerable interface, it's displayed as a collection (see the cds node in the picture above) otherwise it's displayed as another internal node (see the source node). If the item with the IEnumerable interface implements the ICollection interface or is an Array in addition the number of items is displayed as well. The text of every displayed internal node is obtained by calling the ToString method on the node object (the same way like in the Quick Watch in the Visual Studio).

The BuildTitle method formats the appearance of leaf nodes. Strings are displayed in apostrophes, numbers without, decimal numbers are displayed with a precision at two decimal places. Dates are displayed as dates. There is a special NullDateTime property and if the date has the same value like it, it's displayed as null.

Names of all members can be translated to a user-friendly format if the TranslateName method is overriden. For example the member name TrxNum can be translated as Transaction number.

Data Input and Output

The Catalog content is deserialized from an XML data file because it's just the simplest way to populate a structure with some data. In real applications, the structure is usually populated from a database or another data source.

In this sample project, there is an additional functionality in the middle layer of the builder. It sets the Tag property of the TreeNode in every internal node and list item. If the node is selected, the user can serialize its whole content to a file which can be used later for reporting bugs or similar purposes.

In fact, the middle layer can have various implementations. In the sample application, I use the standard System.Windows.Forms.TreeView. But our company uses our own visual components which are based on DataSets. The middle layer does not need to have a visual output at all. The output can be saved to a database or to an XML file.

Related Stuff

History

  • 26th November, 2007: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Daniel Smolka
Web Developer
Czech Republic Czech Republic
I started to write my first programs more than 15 years ago on C64, later on Amiga computers. I'm from a small Czech town but after I finished my university I moved to Prague where a worked as a developer/consultant for about five years. Now I've been for more than a year in London, looking for some fun and experience.
 
Apart my work I like travelling, dancing and cats.

Comments and Discussions

 
GeneralGreat job Pinmemberflankerfc6-Jan-08 7:57 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140721.1 | Last Updated 26 Nov 2007
Article Copyright 2007 by Daniel Smolka
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid