SIGN UP MEMBER LOGIN:    
ARTICLE

Customized Solution & Project Explorer in .NET Using C# and Windows Forms

Posted by Sateesh Arveti Articles | C# Assemblies March 22, 2007
This application will allows to see project or solution contents in structure similar to Solution Explorer.
Reader Level:
Download Files:
 

.NET is been in action for past so many years. But, still Project or Solution files are not familiar to most of the programmers. The reason behind this is Visual Studio is going take care of project and solution files. But, if the project or solution contents are more, than it will take long time just to load and show contents of it in Solution Explorer of VS.


In most of the situations, we just need to know files, references and its contents present in a project or list of projects present in a solution. This application will allow us to see any project's or solution's contents as in Solution Explorer view without loading heavy process VS.NET. I designed this application using C#, Windows Forms in .NET.


Before explaining its design and functionality, I will explain little bit about its features.


Features of this Application:

  • Loads any C# Project and allows to explore its contents.
  • Loads any Solution and allows to see list of the projects and its contents.
  • In-built support for displaying xml data in both XML and Data (Grid) View.
  • Support to explore references (.dll) like an object browser in VS.
  • Fast in loading when compared to Solution Explorer of VS.
  • Ability to maintain list of recent files opened through this application. 

Steps to create:

Create a new Windows Forms Project in C# and name it as SolutionExplorer.


Then place the controls as shown in below figure:

ImageNew1.jpg

I will explain the purpose of each control on the startup form (Form1):

I placed a TreeView control and ImageList to display selected project or solution contents with images on each node.

Then I added a TabControl, in one tab I placed a RichTextBox and in another tab, a datagrid control. Later, add menuitems to MainMenu as shown in Figure. Add context Menu with following items:

  1. Expand,
  2. Collapse,
  3. Full Expand,
  4. Grid View

And set context menu property of TreeView to this control.

Finally add an OpenFileDialog and tooltip control.

By using FileDialog control, we can select any C# project file or Solution file to analyze and display its contents in TreeView.

ContextMenu for TreeView is used to expand, collapse and display xml in Grid.

I will explain what I have done in Click of Browse menuitem:

 

if(DialogResult.OK == dglopensoln.ShowDialog())

{

    string selectedprjfile = dglopensoln.FileName.ToString();

    txtsolnpath.Text = selectedprjfile;

    toolTip1.SetToolTip(txtsolnpath,selectedprjfile);

    MenuItem testitem = new MenuItem(selectedprjfile);

    testitem.Click += new EventHandler(testitem_Click);

    mnurecent.MenuItems.Add(testitem);

    obj1.Text = selectedprjfile;

    menuItem7_Click(sender,e);

}


By using above code, we can browse selected project file (.csproj) or solution (.soln) and than we are creating a new menuitem with text as selected file path and a handler for click of that menuitem.Than, we are calling internally calling click of analyze menuitem.

Here, I will explain the logic to load Solution and its contents into treeview control. I almost followed similar logic to load project also.

 

string prevselfilecontents = selfilecontents.Text;

try

{

    selfilecontents.Text = "";

    treeView1.Nodes.Clear();

    menuItem7.Enabled = false;

    TreeNode mainnode = null;

    string httpprjs = null;

    if(txtsolnpath.Text.EndsWith(".sln"))

    {

        string tmpsolndata = @"c:\tempsoln.xml";

        string solnname = Path.GetFileNameWithoutExtension(txtsolnpath.Text);

        mainnode = new TreeNode(solnname);

        treeView1.Nodes.Add(mainnode);

        if(Directory.Exists(@"C:\"+solnname))

        {

            Directory.Delete(@"C:\"+solnname,true);

        }

        Directory.CreateDirectory(@"C:\"+solnname);

        prjsdetailsinsoln = new Hashtable();

        if(!File.Exists(tmpsolndata))

        {

            File.Create(tmpsolndata);

        }

        string solncontents = "";

        StreamReader solnreader = new StreamReader(txtsolnpath.Text.Trim());

        while(solncontents != null)

        {

            solncontents = solnreader.ReadLine();

            if(solncontents != null)

            {        
                try

                {

                    if(solncontents.StartsWith("Project"))

                    {

                        string[] prjprops = solncontents.Split(',');

                        string prjdispname = prjprops[0].Substring(prjprops[0].LastIndexOf("=")+1).Replace("\"","").Trim();

                        string prjpath1   = prjprops[1].ToString().Replace("\"","").Trim();

                        prjsdetailsinsoln.Add(prjdispname,prjpath1);

                    }

                }

                catch(Exception ex)

                {

                    MessageBox.Show(ex.Message);

                }

            }

        }

        IDictionaryEnumerator enprj = prjsdetailsinsoln.GetEnumerator();

        while (enprj.MoveNext())

        {

            string strprjname = enprj.Key.ToString();

            if(enprj.Value.ToString().IndexOf("http://") == -1 && enprj.Value.ToString().EndsWith(".csproj"))

            {

                string prjpath = txtsolnpath.Text.Substring(0,txtsolnpath.Text.LastIndexOf(@"\")+1)+enprj.Value.ToString();

                if(File.Exists(prjpath))

                {

                    StreamReader prjreader = new StreamReader(prjpath);

                    string prjcontents = prjreader.ReadToEnd();

                    prjreader.Close();

                    //Format Project File into XML file...

                    tmpxmlfileforsolndata = @"C:\"+solnname+"\\"+enprj.Key.ToString()+".xml";

                    if(prjcontents.Length != 0)

                    {

                        StreamWriter solntoxmlconverter = new StreamWriter(tmpxmlfileforsolndata,false);

                        solntoxmlconverter.Write("<?xml version=\"1.0\"?>");

                        solntoxmlconverter.Write(prjcontents);

                        solntoxmlconverter.Close();

                    }

                    else

                    {

                        MessageBox.Show("Selected Project File is empty...");

                        txtsolnpath.Text = "";

                    }

                    //General project's Details....

                    TreeNode rootnode = new TreeNode();

                    rootnode.Text = strprjname;

                    mainnode.Nodes.Add(rootnode);

                    //Project's references information...

                    TreeNode referencenode = new TreeNode();

                    referencenode.Text = "References";

                    rootnode.Nodes.Add(referencenode);

                    //aspx Files Included in the Project...

                    TreeNode includedaspxfilesnode = new TreeNode();

                    includedaspxfilesnode.Text = "ASPX Files";

                    rootnode.Nodes.Add(includedaspxfilesnode);

                    //aspx.cs Files Included in the Project...

                    TreeNode includedaspxcsfilesnode = new TreeNode();

                    includedaspxcsfilesnode.Text = "ASPX.CS Files";

                    rootnode.Nodes.Add(includedaspxcsfilesnode);

                    //Class  Files Included in the Project...

                    TreeNode includedcsfilenode = new TreeNode();

                    includedcsfilenode.Text = "Class Files";

                    rootnode.Nodes.Add(includedcsfilenode);

                    //Class  Files Included in the Project...

                    TreeNode includedusercntrlfilenode = new TreeNode();

                    includedusercntrlfilenode.Text = "User Controls";

                    rootnode.Nodes.Add(includedusercntrlfilenode);

                    //Web config Files Included in the Project...

                    TreeNode includedwebconfignode = new TreeNode();

                    includedwebconfignode.Text = "Web Config Files";

                    rootnode.Nodes.Add(includedwebconfignode);

                    //Javascript Files Included in the Project...

                    TreeNode includedjsfilenode = new TreeNode();

                    includedjsfilenode.Text = "JavaScript Files";

                    rootnode.Nodes.Add(includedjsfilenode);

                    //CSS  Files Included in the Project...

                    TreeNode includedcssfilenode = new TreeNode();

                    includedcssfilenode.Text = "CSS Files";

                    rootnode.Nodes.Add(includedcssfilenode);

                    //Image  Files Included in the Project...

                    TreeNode includedimgfilenode = new TreeNode();

                    includedimgfilenode.Text = "Image Files";

                    rootnode.Nodes.Add(includedimgfilenode);

                    //XML  Files Included in the Project...

                    TreeNode includedxmlfilenode = new TreeNode();

                    includedxmlfilenode.Text = "XML Files";

                    rootnode.Nodes.Add(includedxmlfilenode);

                    //XSL  Files Included in the Project...

                    TreeNode includedxslfilenode = new TreeNode();

                    includedxslfilenode.Text = "XSL Files";

                    rootnode.Nodes.Add(includedxslfilenode);

                    //Other  Files present in unknown format Included in the Project...

                    TreeNode includedunknownfilenode = new TreeNode();

                    includedunknownfilenode.Text = "Unknown Files";

                    rootnode.Nodes.Add(includedunknownfilenode);

                    //To Load all items of the Project into the Treeview...

                    XPathDocument prjfile = new XPathDocument(tmpxmlfileforsolndata);

                    XPathNavigator nav = prjfile.CreateNavigator();

                    //TO Load all references of the selected Project...

                    XPathNodeIterator referenceiterator = nav.Select

                    (@"/VisualStudioProject/CSHARP/Build/References/Reference");

                    while(referenceiterator.MoveNext())

                    {

                        string reffile = referenceiterator.Current.GetAttribute("Name","").ToString();

                        TreeNode refnode = new TreeNode(reffile);

                        if(reffile.StartsWith("System"))

                        {

                            refnode.ForeColor  = Color.Green;

                        }

                        else

                        {

                            refnode.ForeColor = Color.Orange;

                        }

                        referencenode.Nodes.Add(refnode);

                    }

                    //TO Load all ASPX of the selected Project...

                    XPathNodeIterator aspxfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("aspx",includedaspxfilesnode,aspxfileiterator);

                    RemoveUnwatedNodes(includedaspxfilesnode);

                    //TO Load all ASPX.CS(Code-Behind) of the selected Project...

                    XPathNodeIterator aspxcsfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("aspx.cs",includedaspxcsfilesnode,aspxcsfileiterator);

                    RemoveUnwatedNodes(includedaspxcsfilesnode);

                    //TO Load all Assembly Config of the selected Project...

                    XPathNodeIterator webconfigfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("config",includedwebconfignode,webconfigfileiterator);

                    RemoveUnwatedNodes(includedwebconfignode);

                    //TO Load all Assembly Config of the selected Project...

                    XPathNodeIterator jsfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("js",includedjsfilenode,jsfileiterator);

                    RemoveUnwatedNodes(includedjsfilenode);

                    //TO Load all CSS files of the selected Project...

                    XPathNodeIterator cssfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("css",includedcssfilenode,cssfileiterator);

                    RemoveUnwatedNodes(includedcssfilenode);

                    //TO Load all Image files of the selected Project...

                    XPathNodeIterator imgfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("gif",includedimgfilenode,imgfileiterator);

                    RemoveUnwatedNodes(includedimgfilenode);

                    //TO Load all XML files of the selected Project...

                    XPathNodeIterator xmlfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("xml",includedxmlfilenode,xmlfileiterator);

                    RemoveUnwatedNodes(includedxmlfilenode);

                    //TO Load all XSL files of the selected Project...

                    XPathNodeIterator xslfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("xsl",includedxslfilenode,xslfileiterator);

                    RemoveUnwatedNodes(includedxslfilenode);

                    //TO Load all Class files of the selected Project...

                    XPathNodeIterator csfileiterator = nav.Select

                    (@"/VisualStudioProject/CSHARP/Files/Include/File");                      

                    LoadselectedDetails("cs",includedcsfilenode,csfileiterator);

                    RemoveUnwatedNodes(includedcsfilenode);

                    //TO Load all User Controls files of the selected Project...

                    XPathNodeIterator usercntrlsfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    LoadselectedDetails("ascx.cs",includedusercntrlfilenode,usercntrlsfileiterator);

                    RemoveUnwatedNodes(includedusercntrlfilenode);

                    //TO Load all Unknown files of the selected Project...

                    XPathNodeIterator unknownsfileiterator = nav.Select(@"/VisualStudioProject/CSHARP/Files/Include/File");

                    while(unknownsfileiterator.MoveNext())

                    {

                        string filename = unknownsfileiterator.Current.GetAttribute("RelPath","").ToString().ToLower();

                        if(!filename.EndsWith(".aspx") && !filename.EndsWith(".aspx.cs") && !filename.EndsWith(".cs") && !

                            filename.EndsWith(".ascx.cs") && !filename.EndsWith(".js") &&  !filename.EndsWith(".xml") && !

                            filename.EndsWith(".xsl") && !filename.EndsWith(".css") &&  !filename.EndsWith(".gif") &&  !

                            filename.EndsWith (".config"))

                        {

                            includedunknownfilenode.Nodes.Add(filename.Substring(filename.LastIndexOf(@"\")+1));

                        }

                    }

                    RemoveUnwatedNodes(includedunknownfilenode);

                }

                else

                {

                    TreeNode httpprjnode = new TreeNode(enprj.Value.ToString());

                    httpprjnode.ForeColor = Color.Red;

                    mainnode.Nodes.Add(httpprjnode);

                }

            }

            if(enprj.Value.ToString().IndexOf("http://") != -1)

            {

                httpprjs+=enprj.Value.ToString()+"#";

            }

        }

        foreach(string httpprj in httpprjs.Split(new char[]{'#'}))

        {

            if(httpprj.Trim() != "")

            {

                TreeNode node = new TreeNode(httpprj.Trim());

                mainnode.Nodes.Add(node);

            }

        }

    }

}

catch(Exception ex)

{

    MessageBox.Show(ex.Message);

    selfilecontents.Text = prevselfilecontents;

}

finally

{

    menuItem7.Enabled = true;

}

 

In this click event, we are first finding whether selected file is a project file or solution file by using its extension. Since, Solution file will not be in xml format. So, I am using some text search patterns to get project details present in the solution file.

I am looping foreach project present in solution, creating a temporary xml file to store project contents and than create a structure in treeview with nodes named as aspx, user controls like that we can add any number of nodes based on types of files present in your project. I am using XPath to navigate through project file present in xml format.

I am using Xpath statement as @"/VisualStudioProject/CSHARP/Build/References/Reference" to get all project's references and @"/VisualStudioProject/CSHARP/Files/Include/File" to get all files included in project.

Based on their extension, I am adding each item to specific node like adding .aspx files to ASPX Node...Than, I am removing nodes which don't have any items in it. Finally, I am formatting treeview for good look.

Then we required displaying contents of selected file in treeview.So, I am AfterSelect event of treeview, to display its contents.

Here, I am going to get absolute physical path of selected file by using a HashTable which is created at that time of creating nodes foreach file type present in the project or solution. I am getting absolute path of selected file by using selected item's text and searching its path attribute in its corresponding project file. After getting its path, I am reading its entire contents and displaying in richtextbox.

Then add another form to get internal details of selected reference. And create UI as shown in figure:

Img2.jpg

Here, I placed a menu, FileDialog, tooltip followed by a treeview to display selected reference details.

In Load Click, I am getting selected reference path and using reflection, we are displaying its namespaces, classes, events, methods in treeview.

The Final output will be like this:


Img3.jpg

Img4.jpg

We can still enhance this application with better UI and support of all files types and multiple language project file exploration.

I am attaching code for further reference. I hope this code will be useful for all.

Login to add your contents and source code to this article
share this article :
post comment
 

hav a doubt. U exist here?

Posted by kg balajee Feb 22, 2012

d

Posted by rakesh patel Oct 11, 2008

Code is attached to the article in ZIP format.You can see topmost right side of the window....Click on Download Files Link...

Posted by Sateesh Arveti Apr 09, 2007

where is code dude :)

Posted by mian ghous Apr 06, 2007
Team Foundation Server Hosting
Become a Sponsor
PREMIUM SPONSORS
  • ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications. Visit DynamicPDF here
    The leading .NET charting control now features PDF, Flash and Silverlight export, visualization of large datasets and more. Deliver true charting functionality to your BI, Scorecard, Presentation or Scientific apps. Download evaluation now.
6 Months Free & No Setup Fees ASP.NET Hosting!
Become a Sponsor