3

I have a list containing Client objects. I want to sort the list by using it's property name ascending or descending, which I already have in the code in viewstate : ViewState("PropertyName") and ViewState("Order")

Dim objList As List(Of Client) = Session("ClientList")  
objList.Sort(ViewState("PropertyName") + " " + ViewState("Order"))    
datarepeater.datasource = objList

How can I achieve this ?

2
  • Do you really need to store the property-name in the ViewState? Then i would use a DataTable instead where you can use the column-name and LINQ to order it. Commented Mar 7, 2014 at 14:31
  • If I go that route then I have to convert my list into a datatable which I want to avoid. Commented Mar 7, 2014 at 14:45

2 Answers 2

4

Normally, if you knew the property with which you wanted to sort, you would be able to just do something like this:

clients.Sort(Function(x, y) x.Name.CompareTo(y.Name))

In the above example, I am, of course sorting on the Name property (I don't know what properties the Client class has, I'm just using it as an example.

However, since you don't know which property you are going to use until run-time, you'll need to do something more complicated. If you really want to use the actual property names of the class, you could use Reflection to retrieve the value of the property dynamically, for instance:

clients.Sort(Function(x, y)
                 Dim xProperty As PropertyInfo = x.GetType().GetProperty(ViewState("PropertyName").ToString)
                 Dim yProperty As PropertyInfo = y.GetType().GetProperty(ViewState("PropertyName").ToString)
                 Dim xValue As Object = xProperty.GetValue(x)
                 Dim yValue As Object = yProperty.GetValue(y)
                 Return xValue.ToString().CompareTo(yValue.ToString())
             End Function)

To reverse the sort order, just multiply the return value by -1, or switch which object you are comparing to what. For instance:

If ViewState("Order") = "Ascending" Then
    Return xValue.ToString().CompareTo(yValue.ToString())
Else
    Return yValue.ToString().CompareTo(xValue.ToString())
End If
Sign up to request clarification or add additional context in comments.

5 Comments

Thanks Steven however I get an Option stric disallows converting from object to String in the ViewState("PropertyName").SO I added a ToString. After that I get error msg "Overload resolution failed because no accessible "GetValue" accepts this number of arguments. I didn't add any arguments. Here is what I have: objList.Sort(Function(x, y) Dim xValue As String = x.GetType().GetProperty(ViewState("PropertyName").ToString).GetValue(x).ToString() Dim yValue As String = y.GetType().GetProperty(ViewState("PropertyName").ToString).GetValue(y).ToString() Return xValue.CompareTo(yValue) End Function)
On this site, is it possible to post instead of "adding a comment" it would make my message easier to read.
No, unfortunately, the only way to post properly formatted code is to edit your original question to include the new code. I think the reason why you are getting that error is because you are targeting an older version of the framework. The overload that takes just one parameter wasn't added until .NET Framework version 4.5. In that case, just add Nothing as the second parameter, for instance: xProperty.GetValue(x, Nothing).
Thanks I can't believe I missed that....Yes I am using Framework 4.0. Thanks again for the solution. I really have to get used to LINQ and LAMBDA's. Just hard to change a 15 year for...each "coding reflex"...
Yes, well, you could also use a delegate to a regular named method or create a class that implements IComparer. The same principles apply. The lambda expressions can be very handy for this sort of thing, though.
1

You can also use Linq (using the same general method proposed by Steven Doggart):

sorted = lst.OrderBy(Function(x) x.GetType().GetProperty(_strColumnName01).GetValue(x)). _
             ThenBy(Function(x) x.GetType().GetProperty(_strColumnName02).GetValue(x)).ToList()

In my particular example, I needed to sort by two columns, but for just a single column:

sorted = lst.OrderBy(Function(x) x.GetType().GetProperty(_strColumnName01).GetValue(x)).ToList()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.