Collapse folders and projects in Visual Studio

Thursday, July 16, 2009 Labels: ,

I consider the PowerCommands for Visual Studio 2008 invaluable. And, the collapse all feature is certainly one of my most used features. However, if a solution folder is already collapsed, the projects underneath are skipped.

So, I found a great macro for collapsing all solution folders and their projects, regardless of whether or not the parent solution folder(s) are open or closed.

Visual Studio 2005 Collapse All Macro

(yes, it works for Visual Studio 2008, what I primarily use)

 

For convenience, here is the macro source code:

    Sub CollapseAll()

' Get the the Solution Explorer tree
Dim solutionExplorer As UIHierarchy
solutionExplorer = DTE.Windows.Item(Constants.vsext_wk_SProjectWindow).Object()

' Check if there is any open solution
If (solutionExplorer.UIHierarchyItems.Count = 0) Then
Return
End If

' Get the top node (the name of the solution)
Dim rootNode As UIHierarchyItem = solutionExplorer.UIHierarchyItems.Item(1)
rootNode.DTE.SuppressUI = True

' Collapse each project node
Collapse(rootNode, solutionExplorer)

' Select the solution node, or else when you click
' on the solution window
' scrollbar, it will synchronize the open document
' with the tree and pop
' out the corresponding node which is probably not what you want.

rootNode.Select(vsUISelectionType.vsUISelectionTypeSelect)
rootNode.DTE.SuppressUI = False

End Sub

Private Sub Collapse(ByVal item As UIHierarchyItem, ByRef solutionExplorer As UIHierarchy)

For Each innerItem As UIHierarchyItem In item.UIHierarchyItems
If innerItem.UIHierarchyItems.Count > 0 Then

' Re-cursive call
Collapse(innerItem, solutionExplorer)

' Collapse
If innerItem.UIHierarchyItems.Expanded Then
innerItem.UIHierarchyItems.Expanded = False
If innerItem.UIHierarchyItems.Expanded = True Then
' Bug in VS 2005
innerItem.Select(vsUISelectionType.vsUISelectionTypeSelect)
solutionExplorer.DoDefaultAction()
End If
End If

End If
Next

End Sub

Just had a funny thought...

Friday, August 17, 2007 Labels: ,
I was just thinking how much I love JavaScript and how it has been my favorite language/platform for years. People who consider themselves 'real' developers have always given me a hard time because of it. That and "you can use it just like an OOP language, but it's not really one"! Haha! Who cares if it only acts like it!?

How could you not love it? It's so dynamic - you can do anything you want with it!

It's funny that everyone is getting excited about the DLR in upcoming .Net releases. And, "it's so cool, because it supports dynamic language extensions to C#." Hehehe.. Well, at least the rest of the world is finally starting to catch up to me.. 8^)

Output name/values of an Enum

Wednesday, March 28, 2007 Labels: , ,

I took the time a while ago to figure out the best way to output each name and value in an Enum. I just keep using the code and have been looking in recent projects looking for the code to re-use in a new project. So, I thought I’d share the love..

This code will output the name and value of each element in the MyEnum object.


string[] names = Enum.GetNames(typeof(MyEnum));
Array values = Enum.GetValues(typeof(MyEnum));
for (int i = 0; i < names.Length; i++)
{
Console.WriteLine(string.Format("{0} = {1}", names[i], values.GetValue(i)));
}


I think Reflection is probably the most overlooked and under-appreciated assembly in the whole .Net framework. Don’t you just love it? 8^)

Use Reflection to compare Class properties with Enum element names

Tuesday, March 6, 2007 Labels: , ,

The following code demonstrates how to use Reflection to simply your code; making it easier to read and understand, and remove code for potential bugs.

The "normal" way of assigning/comparing Enum elements with class properties. In this example, the code must be changed every time you change the user class or the DataField enum. That's a major pain in the neck!

public class User
{
public string FirstName;
public string LastName;
public string EmailAddress;
public User() { }
}

public enum DataField
{
FirstName,
LastName,
EmailAddress,
}

string value = "";
switch (field.DataField)
{
case DataField.FirstName: value = currentUser.FirstName;
break;
case DataField.LastName: value = currentUser.LastName;
break;
case DataField.EmailAddress: value = currentUser.EmailAddress;
break;
default: value = "";
break;
}

Using the switch statement above, you'd have to modify it whenever you add more properties of your User class..

But, by using the following code, you won't ever have to modify the switch statement because it isn't even needed anymore.

public class User
{
public int PlanType;

public string FirstName;
public string LastName;
public string EmailAddress;

public string Address;
public string City;
public string State;
public string PostalCode;
public string Country;
public string PhoneNumber;

public string CreditCardName;
public string CreditCardType;
public string CreditCardNumber;
public string CreditCardExpirationMonth;
public string CreditCardExpirationYear;

public User() { }
}

public enum DataField
{
Unknown,
PlanType,
FirstName,
LastName,
EmailAddress,
Address,
City,
State,
PostalCode,
Country,
PhoneNumber,
CreditCardName,
CreditCardType,
CreditCardNumber,
CreditCardExpirationMonth,
CreditCardExpirationYear
}

string value = "";
FieldInfo[] properties = currentUser.GetType().GetFields();
for (int i = 0; i < properties.Length; i++)
{
if (properties[i].Name == field.DataField.ToString())
{
Object obj = properties[i].GetValue(currentUser);
if (null != obj)
value = (string)obj;
break;
}
}


Of course, you'll still have to ensure that the DataField enum and the User class properties are kept in sync, but you don't ever have to modify your for loop. That's cool!
Older Posts