Search This Blog

Tuesday, February 9, 2010

Sorting ListViewItems by Date, Number or String

As shown in this article, you can sort a ListView items by date.
This code is very slow however.
Here’s an improved version which also handles sorting of numbers.

First create a static Dictionary in your MainForm, like this:

internal static Dictionary<int, ListViewColumnSorter.cDataType> columnType = new Dictionary<int,ListViewColumnSorter.cDataType>();

cDataType
is an enum:
public enum cDataType
{
    number, datetime, text
}

When re-loading your ListView, or when changing the columns, clear the Dictionary, because the data type of the column can change.





public int Compare(object x, object y)
{
    int compareResult;
    ListViewItem listviewX, listviewY;

    // Cast the objects to be compared to ListViewItem objects
    listviewX = (ListViewItem)x;
    listviewY = (ListViewItem)y;

    // Compare the two items

    //Determine data type of object
    string objectX = listviewX.SubItems[ColumnToSort].Text;
    string objectY = listviewY.SubItems[ColumnToSort].Text;
    cDataType dType = cDataType.text;
    if (!MainForm.columnType.TryGetValue(ColumnToSort, out dType))
    {
        long tempLong;
        DateTime tempDateTime;

        if (Int64.TryParse(objectX, out tempLong))
        {
            MainForm.columnType.Add(ColumnToSort, cDataType.number);
        }
        else if (DateTime.TryParse(objectX, out tempDateTime))
        {
            MainForm.columnType.Add(ColumnToSort, cDataType.datetime);
        }
        else
        {
            MainForm.columnType.Add(ColumnToSort, cDataType.text);
        }
    }

    switch (MainForm.columnType[ColumnToSort])
    {
        case cDataType.number:
            compareResult = ObjectCompare.Compare(Convert.ToInt64(objectX), Convert.ToInt64(objectY));
            break;

        case cDataType.datetime:
            compareResult = ObjectCompare.Compare(DateTime.Parse(objectX), DateTime.Parse(objectY));
            break;

        default:
            compareResult = ObjectCompare.Compare(objectX, objectY);
            break;
    }
   

    // Calculate correct return value based on object comparison
    if (OrderOfSort == SortOrder.Ascending)
    {
        // Ascending sort is selected, return normal result of compare operation
        return compareResult;
    }
    else if (OrderOfSort == SortOrder.Descending)
    {
        // Descending sort is selected, return negative result of compare operation
        return (-compareResult);
    }
    else
    {
        // Return '0' to indicate they are equal
        return 0;
    }
}

Friday, February 5, 2010

App-V Icons

While programming the App-V Self Support tool I noticed that application Icons are stored in a lot of different places.

Here’s some places where you can look for:

1: User’s Icon Cache. By default located in %Appdata%\Softgrid Client\Icon Cache
 Note that you have to now the GUID of the app you're trying to fetch.
Use WMI for that, or the OSD file.


2: Public Icon Cache. By Default located in Public Documents
 


3: A direct approach: In the folder where the SFT and OSD of the package reside:
You can use code like this:
string orgOsdPath = "";
RegistryKey appsKey = appVKey.OpenSubKey("Applications");
orgOsdPath = appsKey.OpenSubKey(<<Full Name of App-V application>>).GetValue("OriginalDescriptionURL").ToString();
DirectoryInfo di = new DirectoryInfo(Path.GetDirectoryName(orgOsdPath));

string icopath = di.FullName + "\\" + di.Name + " Icons\\" + Path.GetFileNameWithoutExtension(orgOsdPath) + ".ico";if(File.Exists(icopath))
{
    Do something with: icopath;
}