Archive

Archive for August, 2006

Sorting and Filtering Objects within Generic Lists

August 29th, 2006 Michael Bell No comments

I started working with Generics about 6 months ago. The main reason is because I just now started using custom objects for just about everything in my applications. It was a bit of a pain in the rear when I found out the GridView sort didn’t ‘just work’ when you bound it to a generic collection like the way it does when you bind it to a dataset. The other caveat I found was that it was more difficult to filter. I couldn’t just use DataViews or a Select on the table in the DataSet. I had to create some new functionality for filtering and sorting for generics. Here are my examples.

This first method takes a generic list as a parameter and passes the same list back, but sorted. Note that this requires the Comparison Generic Delegate listed down the page further. Substitute in your own custom object for my “ImageObject”:
// Pass in a generic list of objects (ImageObjects in my case) you want sorted, and by what property you want it sorted.
public List<ImageObject> sortImageList(List<ImageObject> ImageList, string sortExpression)
{
    SortExp = sortExpression;

    if (sortExpression != string.Empty)
    {
        Comparison<ImageObject> compare;
        compare = new Comparison<ImageObject>(CompareBy);
        ImageList.Sort(compare);
    }

    return ImageList;
}

This version does the same thing as the last, but, instead of passing in a List, it grabs one from the data access layer, sorts it, then returns it. Note that this requires the Comparison Generic Delegate listed down the page further. Substitute in your own custom object for my “ImageObject”:
public List<ImageObject> sortImageList(int OwnerID, UserData.ImageLookupType LookupType, bool sort, string sortExpression)
{
    List<ImageObject> list = _UserData.getImageList(OwnerID, LookupType);

    SortExp = sortExpression;

    if (sortExpression != string.Empty)
    {
        Comparison<ImageObject> compare;
        compare = new Comparison<ImageObject>(CompareBy);
        list.Sort(compare);
    }

    return list;
}

Here is the Comparison Generic Delegate that does our object comparison and bubbles them into order. Substitute your own objects’ property names:
private int CompareBy(ImageObject Image1, ImageObject Image2)
{
    int iRet = 0;
    switch (_SortExp)
    {
        case “Name”:
        case “Name ASC”:
            iRet = Image1.Name.CompareTo(Image2.Name);
            break;
        case “Name DESC”:
            iRet = Image2.Name.CompareTo(Image1.Name);
            break;
        case “DateUploaded”:
        case “DateUploaded ASC”:
            iRet = Image1.DateUploaded.CompareTo(Image2.DateUploaded);
            break;
        case “DateUploaded DESC”:
            iRet = Image2.DateUploaded.CompareTo(Image1.DateUploaded);
            break;
        case “Views”:
        case “Views ASC”:
            iRet = Image1.Views.CompareTo(Image2.Views);
            break;
        case “Views DESC”:
            iRet = Image2.Views.CompareTo(Image1.Views);
            break;
    }

    return iRet;
}

This leaves us with filtering. In this first method, you pass in a full list and return a single object based on the filter criteria:
public ImageObject FilterByImageID(List<ImageObject> ImageList, int ImageID)
{
    Predicate<ImageObject> filterByImageID;
    ImageIDFilter filter = new ImageIDFilter(ImageID);
    filterByImageID = new Predicate<ImageObject>(filter.FilterByImageID);
    return ImageList.Find(filterByImageID);
}

The ImageIDFilter is the name of teh class I created to do the actual
comparison of the object in the lists property to the criteria I’ve
passed in:
private class ImageIDFilter
{
    private int _ImageID;

    public bool FilterByImageID(ImageObject Image)
    {
        return (Image.ImageID == _ImageID);
    }

    public ImageIDFilter(int ImageID)
    {
        _ImageID = ImageID;
    }
}

There is also a shorthand version of this same method:
ImageObject io = myGenericList.Find(delegate(ImageObject image) { return image.Image == _ImageID; });

The latter would be much easier for simple filters, whereas the former best for more complex filtering.

Categories: ASP.NET, c# Tags:

Effective Data Paging in SQL 2005

August 25th, 2006 Michael Bell No comments

I’m in a spot where I need effective paging. My table has 500k rows and it would suck to select the whole shebob everytime the web page gets viewed, as it does when you use paging built into the datagrid or dataadapter. So, after a little research, I found some new functionality in SQL 2k5 that helps in this arena.

Sample:

CREATE PROCEDURE dbo.usp_testPaging
(
    @PageSize [int] = -1,
    @CurrentPage [int] = -1
)

WITH ImageList As (
     SELECT
        ROW_NUMBER() OVER (ORDER BY Views ASC) AS rownum,
        ImageID,
        Views
     FROM Images WHERE [Public]=1)

SELECT
    ImageID,
    Views
FROM ImageList
WHERE
    rownum BETWEEN (@CurrentPage-1)*@PageSize+1 AND @CurrentPage*@PageSize

This will bring back the actual records you want instead of the whole table. Def. some overhead saved here.

I found a great help page here on the subject.

Categories: ASP.NET, SQL 2005 Tags:

Ampersand Issues in Code

August 22nd, 2006 Michael Bell No comments

This is something that’s ticked me off repeatedly in the last few months. When I try to put a URL in say… the OnClientClick property of a ImageButton, and the URL has more than one argument (blah.aspx?a=1&b=2), the & gets replaces with &amp;. This takes place I guess in the Render or RenderControl method. This also happens in Page.ClientScript.GetPostBackEventReference, and I’m sure these aren’t the only spots. Annoying!!! My only fix so far is just in the OnClickClick, call a javascript function that does yoru redirect, and pass it arguments.

Categories: Uncategorized Tags:

Upload with Progress Bar

August 21st, 2006 Michael Bell No comments

I found an awesome control for uploading via web browser, WITH a progress bar. Dean Brettle is the author, and his website is at: http://www.brettle.com . It’s a .NET control and it’s very easy to use.

I did have a need for multiple upload controls in a single page, with the option to add more as needed. The upload control didn’t have the capability built in to handle a collection, so I created one myself with the use of the System.Collections.Generic namespace. This is the code I used for uploading multiple images:

1. Included the System.Collections.Generic namespace

2. Added this generic property to my class:

List<InputFile> _InputFileCollection = new List<InputFile>();
    public List<InputFile> InputFileCollection
    {
        get
        {
            foreach (Control ctrl in this.Controls)
            {
                if (ctrl.GetType() == typeof(InputFile))
                {
                    _InputFileCollection.Add((InputFile)ctrl);
                }
            }
            return _InputFileCollection;
        }
    }

3. On the button click/upload event:

foreach (InputFile file in InputFileCollection)
        {
            if(file.HasFile)
           {
               _CurrentImageName = file.FileName;
               if(File.Exists(SavePath + _CurrentImageName))
               {
                   int i = 0;
                   while(File.Exists(SavePath + _CurrentImageName))
                   {
                       string s = file.FileName;
                       int dotLocation = s.IndexOf(“.”);
                       s = s.Insert(dotLocation,i.ToString());
                       _CurrentImageName = s;
                       i++;
                   }
               }
               file.MoveTo(SavePath + _CurrentImageName, MoveToOptions.Overwrite);
            }
        }

Works fantastically, and you can add all the input controls you want. 

Categories: Uncategorized Tags: