How to sort a generic List

I came across a little issue today, in that I had an Interface object and I needed to be able to sort the list, I would normally implement the IComparable interface on the concreate type, but I don’t have access to the concreate type in my case.

I tried several different methods in the end I ended up with using a delegate, and found in SimoneB Blog, which I have extracted the content below:

Sorting a generic List<T> is pretty straightforward if you know how to do it. With C# 2.0, anonymous methods come at hand, as well as the little known Comparison<T> delegate (check out this post for more information about this class as well as other useful classes new to C# 2.0).

Ok, let’s suppose we have a product class (let me save some space by using C# 3.0 syntax).

 

class Product

{

    public int ProductID { get; set; }

    public string ProductName { get; set; }

    public decimal UnitPrice { get; set; }

}

When we have a list of products we may want to sort it on the ProductName property before displaying it to the user. This can be accomplished with the Sort method of the List<T> class, which defines several overloads. The most handy in this case is the Sort(Comparison<Product>) method and the result is easily achieved with a couple lines of code.

 

List<Product> products = new List<Product>();

 

products.Sort(delegate(Product p1, Product p2)

              {

                  return p1.ProductName.CompareTo(p2.ProductName);

              });

So far so good, but what if we need to sort our list in several places during the execution of our program? Do we have to write that code each time? Actually no, since we can use the parameterless Sort() method of our list class. What this method does is use the “default comparer” to sort the list. So what’s this default comparer? It’s the comparer that’s automatically created if we implement the IComparable<T> interface. This way we can centralize the sorting logic into our class, and just call the parameterless Sort() method on it whenever we need it sorted on the ProductName property.

 

public class Product : IComparable<Product>

{

    […]

 

    public int CompareTo(Product other)

    {

        return ProductName.CompareTo(other.ProductName);

    }

}

Ok, now what if we want to be able to sort it on the other two properties, ProductID and UnitPrice? Do we have to write an anonymous method each time as we did in the beginning? Of course no, since there’s a useful trick which prevents us from needing to do that. We can define two static Comparer<Product> properties in our product class, and supply them as parameters to the Sort(Comparer<T>) method of our list whenever we need it sorted on something which is not the default sorting logic.

 

public class Product : IComparable<Product>

{

    […]

 

    public static Comparison<Product> PriceComparison =

        delegate(Product p1, Product p2)

        {

            return p1.Price.CompareTo(p2.Price);

        };

 

    public static Comparison<Product> IDComparison =

        delegate(Product p1, Product p2)

        {

            return p1.ProductID.CompareTo(p2.ProductID);

        };

 

    […]

}

Since they are static they can be used simply like so: products.Sort(Product.PriceComparison) or products.Sort(Product.IDComparison), which will respectively sort the list by price and id.

 

Below is the full code of the Product class.

 

public class Product : IComparable<Product>

{

    private int id;

    private string prodName;

    private decimal price;

 

    public static Comparison<Product> PriceComparison = delegate(Product p1, Product p2)

                                                        {

                                                            return p1.price.CompareTo(p2.price);

                                                        };

 

    public static Comparison<Product> IDComparison = delegate(Product p1, Product p2)

                                                     {

                                                         return p1.id.CompareTo(p2.id);

                                                     };

 

    public int ProductID

    {

        get { return id; }

        set { id = value; }

    }

 

    public string ProductName

    {

        get { return prodName; }

        set { prodName = value; }

    }

 

    public decimal UnitPrice

    {

        get { return price; }

        set { price = value; }

    }

 

    public Product(int id, string prodName, decimal price)

    {

        this.id = id;

        this.prodName = prodName;

        this.price = price;

    }

 

    #region IComparable<Product> Members

 

    public int CompareTo(Product other)

    {

        return ProductName.CompareTo(other.ProductName);

    }

 

    #endregion

 

    public override string ToString()

    {

        return string.Format(“Id: {0} Name: {1} Price: {2}”, id, prodName, price);

    }

}

Copy one object to another Object

I was in need to copying one concreate object to another concreate object, but I needed the flexability that when a new property is added the method would not need to be changed, also I needed the ability for the method to take in any types.

So the first take was to generate a method that uses reflections to go over the obecjts properts and set the returning object properties.  That was quite simple, then to make the method more flexable I used generics to help with my method, to allow for any types to be used.

One thing to note is that you require the try catch, in case the GetValue or SetValue fails, such as if the object is null.

This is what I ended up with.

Here is the VB.NET method

Here is the C#

 

Only get the data that is needs to be displayed

I have been on the look out for the ability to display and search a customers database, but having the ability to display millions of records if that what the end users wants.  But the trouble is that it can take a long time to return a million records from a data source.

I’ve talked about paging before in my article LINQ-to-SQL-and-Paging, which works fine for internet based paging, but what about WPF and WinForm Grids, well I came across Vitrual Mode for the Microsoft Data Grid, which can provide an answer.  What this allow you to do is, load the data you can see on the screen very quickly and as you scroll through the data is fetched when required.

By setting the VirtualMode = true for a data grid, it allows you to add a handler for deail with CellValueNeeded 

Here is the main body of the code

Each time the Data grid needs some values it will call the following:

And of course the NameListCache class

 

I have attached the source, you will also find a PopulateData project to populate the database with data.

 

DataGridViewVirtualModePaging.zip (19.43 kb)

PopulateData.zip (11.43 kb)

Here are a few of the database scripts that yu will need for the sample

Names.sql (581.00 bytes)

GetNames.sql (786.00 bytes)

Hidden but found on the iPhone

I’ve had an iPhone for a year and a half now, and I’m still finding things it can do, here are a few things that I have found:

  • Pressing the Home button twice quickly takes you to your favorites (this can be configured in the setting)
  • Press Home button while pressing the on/off button causes a Print Screen
  • If you continue to home the Home and on/off button it will perform a reboot of your iPhone
Have you found any more features that I have missed?

 

How to get an EULA displayed for your clickonce application

Stuck with this issue, if needing a ClickOnce installation to display an EULA, I final found a solution, on MSDN

Here’s a round about way to get your clickonce applications to install with an End user license agreement. Basically you build a redistributable component that can be seen in your prerequsites dialog box under the publish window. This allows a nice way to have all your apps reuse the same agreement, if you want. It’s very easy, you need only to create three files (“eula.txt”, “product.xml”, and “package.xml”) and two folders in this case (“EULApackage”, and “en”). I documented everything below on how I set mine up. it works great. the only thing you’ll have to change is the Name of the component and of course you’ll need your own end user licence agreement saved as eula.txt. The component needs to be put in the following path:

Visual Studio 2005

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages

Visual Studio 2008

C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages

in this folder you should see some sub folders for other redistributable components. First make a new sub directory for your component. I called mine EULApackage. in this new folder you need the following. -A file called product.xml and a sub folder called “en” (for english) you can do various things with the product.xml file, but here’s the way mine looks

<?xml version="1.0" encoding="utf-8" ?>

<Product
 
xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"
 
ProductCode="EULA.Bootstrap.Component"
>
 
<!-- Defines list of files to be copied on build -->
 
<PackageFiles>
   
<PackageFile Name="en/eula.txt"/>
 
</PackageFiles>

 
<Commands>
   
<Command PackageFile="en/eula.txt"
     
Arguments='' >
       
<ExitCodes>
<ExitCode Value="0" Result="Success"/>          
<DefaultExitCode Result="Fail" FormatMessageFromSystem="true" String="GeneralFailure" />
       
</ExitCodes>
   
</Command>
 
</Commands>
</Product>

*in this case the file eula.txt was the text file that was my license agreement. Note that it’s not an rtf file. Rtf won’t display propertly using this method.

Now inside my “en” subfolder i put the eula.txt file and another xml file called package.xml, again this xml file can be used to do all kinds of stuff

heres the contents of my version*

 

 <?xml version="1.0" encoding="utf-8" ?>

<Package
 
xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper"
 
Name="DisplayName"
 
Culture="Culture"
 
LicenseAgreement="eula.txt">

   
<PackageFiles>
       
<PackageFile Name="eula.txt"/>
   
</PackageFiles>

 
<!-- Defines a localizable string table for error messages and url's  -->
 
<Strings>
   
<String Name="DisplayName">Companies End User License Agreement</String>
   
<String Name="Culture">en</String>

   
<String Name="CancelFailure">User Failed to Accept Companies End User License Agreement.</String>
   
<String Name="GeneralFailure">A fatal error occurred during the installation of ELUA Component Execution</String>
   
<String Name="AdminRequired">You do not have the permissions required to install this application.  Please contact your administrator.</String>
 
</Strings>    
</Package>

Note: whatever you put in the DisplayName field is what your user will see when he’s confronted with the eula text If you have all this put together correctly and in the right folders, the next time you start up VS2005 and go to your publish tab -> prerequisites you should see the DisplayName field. Just check this as a prerequisite for you app. when the user clicks install on the publish.htm file it’ll present the user with the conents of your eula.txt file inside of a standard license acceptance dialog box. if the choose accept your stuff installs, if they decline then it exits rather nicely and nothing is installed on their systems. If you mess up the formatting for either of the two files or if you leave out the “en” sub folder then the component won’t show up in the prerequisites dialog (when publishing)

Additional notes: although this works great it is a round about method and their are ways around the eula, such as if your publish.htm file allows them to run the application directly (I guess without the bootstrapper starting)but if they click the install button it will run. This also has the benifits of not running every time you publish an update to your clickonce application. They have to run the boot strapper to get the eula to show up (by clicking the install button on publish.htm) I figured out this method by looking at some of the other redistributable components that were already in the path

Visual Studio 2005

C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages

Visual Studio 2008

C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bootstrapper\Packages

You can look in those other components product.xml and package.xml files to see what cool things they’ve done with them.

 

If you are using Visual Studio 2008, you can also set up your project file to include the Package, here is an example below

<BootstrapperPackage Include="EULA.Bootstrap.Component">
  <Visible>False</Visible>
  <ProductName>RPS End User License Agreement</ProductName>
  <Install>true</Install>
</BootstrapperPackage>

Integration Test using the MembershipProvider

Creating tests is a very important part of the development cycle, one of the import part of creating tests is to make sure the tests have as little dependencies as possible, this is where Intergration testing comes in to play.

One area to Integration test is the Membership Provider and Role Provider, this is quite simple as the interfaces ofr both providers are very well defined.

I have attached two Integration test Providers, one for the Membership and the other for Roles, So as to keep Visual Basic alive I’ve written this source in VB.NET

IntegrationTest MembershipProvider.vb (6.24 kb)

IntegrationTestRoleProvider.vb (4.36 kb)

Of course the next step would be to Mock these objects