I have a RadGrid bound to a query result. One of the query fields is an Id value which I use as the DataField value in several GridBoundColumn columns. I've overriden GridBoundColumn.FormatDataValue so I can use the Id to look up an object in a session state collection. Depending on the column's HeaderText value, FormatDataValue returns different properties of the retrieved object.
This all works lovely, except sorting is based on the Id value, not on what's actually in the grid. Furthermore, the UI indicates that all the Id-based columns are the same, presumably because they have the same DataField value. In the attached screenshot, I clicked on the City column. I would expect Chicago to sort ahead of London and Washington, but the rows are sorted by Address Id and the UI shows all the Address Id-based columns as currently sorted.
How can I revise things to make sorting work as I would expect?
Code to reproduce the problem follows.
Please note: I'm not looking for an answer that says, "flatten your data before putting it in the grid." I understand that I could do that. Remember this is a trivial example of a much more complex application. I do not want to avoid the issue I've presented; I want to solve it.
Thank you kindly!
ASPX code:
This all works lovely, except sorting is based on the Id value, not on what's actually in the grid. Furthermore, the UI indicates that all the Id-based columns are the same, presumably because they have the same DataField value. In the attached screenshot, I clicked on the City column. I would expect Chicago to sort ahead of London and Washington, but the rows are sorted by Address Id and the UI shows all the Address Id-based columns as currently sorted.
How can I revise things to make sorting work as I would expect?
Code to reproduce the problem follows.
Please note: I'm not looking for an answer that says, "flatten your data before putting it in the grid." I understand that I could do that. Remember this is a trivial example of a much more complex application. I do not want to avoid the issue I've presented; I want to solve it.
Thank you kindly!
ASPX code:
<%@ Page Language="VB" %>
<%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
<%@ Register TagPrefix="xx" Namespace="Example" %>
<%@ Import Namespace="System.Linq" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<
script
runat
=
"server"
>
Protected Sub grdExample_NeedDataSource(ByVal sender As Object, ByVal e As GridNeedDataSourceEventArgs)
Dim Landmarks() As Landmark
Landmarks = {New Landmark With {.Name = "Wrigley Field", .AddressId = 3}, _
New Landmark With {.Name = "British PM Residence", .AddressId = 1}, _
New Landmark With {.Name = "HofbrÀuhaus", .AddressId = 4}, _
New Landmark With {.Name = "Whitehouse", .AddressId = 2}}
grdExample.DataSource = Landmarks
End Sub
Protected Sub Page_Init(ByVal sender As Object, ByVal e As EventArgs)
If CType(Session.Item("addrCollection"), Address()) Is Nothing Then
Call Session.Add("addrCollection", _
{New Address With {.Id = 1, .Street = "10 Downing St", .City = "London", .PostalCode = "SW1A 2AA", .Province = "England", .Country = "UK"}, _
New Address With {.Id = 2, .Street = "1600 Pennsylvania Ave NW", .City = "Washington", .PostalCode = "20500", .Province = "District of Columbia", .Country = "USA"}, _
New Address With {.Id = 3, .Street = "1060 W. Addison St", .City = "Chicago", .PostalCode = "60613", .Province = "Illinois", .Country = "USA"}, _
New Address With {.Id = 4, .Street = "Am Platzl 9", .City = "Munich", .PostalCode = "D-80331", .Province = "Bavaria", .Country = "Germany"}})
End If
End Sub
</
script
>
<
html
xmlns
=
"http://www.w3.org/1999/xhtml"
>
<
head
runat
=
"server"
>
<
title
>Sorting Issue</
title
>
</
head
>
<
body
>
<
form
id
=
"form1"
runat
=
"server"
>
<
telerik:RadScriptManager
ID
=
"RadScriptManager1"
runat
=
"server"
/>
<
div
>
<
telerik:RadGrid
ID
=
"grdExample"
runat
=
"server"
OnNeedDataSource
=
"grdExample_NeedDataSource"
AllowSorting
=
"true"
AutoGenerateColumns
=
"false"
>
<
MasterTableView
>
<
Columns
>
<
telerik:GridBoundColumn
DataField
=
"Name"
HeaderText
=
"Landmark"
/>
<
telerik:GridNumericColumn
DataField
=
"AddressId"
HeaderText
=
"Address ID"
/>
<
xx:SampleColumn
DataField
=
"AddressId"
HeaderText
=
"Country"
/>
<
xx:SampleColumn
DataField
=
"AddressId"
HeaderText
=
"Province"
/>
<
xx:SampleColumn
DataField
=
"AddressId"
HeaderText
=
"City"
/>
<
xx:SampleColumn
DataField
=
"AddressId"
HeaderText
=
"Street Address"
/>
<
xx:SampleColumn
DataField
=
"AddressId"
HeaderText
=
"Postal Code"
/>
</
Columns
>
</
MasterTableView
>
</
telerik:RadGrid
>
</
div
>
</
form
>
</
body
>
</
html
>
Classes:
Option
Infer Off
Option
Strict
On
Option
Explicit
On
Imports
Telerik.Web.UI
Imports
System.Web.HttpContext
Namespace
Example
Public
Class
SampleColumn
Inherits
GridBoundColumn
Protected
Overrides
Function
FormatDataValue(
ByVal
dataValue
As
Object
,
ByVal
item
As
GridItem)
As
String
Dim
lm
As
Landmark
Dim
Addresses
As
IEnumerable(Of Address)
Dim
address
As
Address
lm =
CType
(item.DataItem, Landmark)
Addresses =
CType
(Current.Session.Item(
"addrCollection"
), Address())
address = Addresses.First(
Function
(a
As
Address) a.Id = lm.AddressId)
Select
Case
MyBase
.HeaderText
Case
"Street Address"
Return
address.Street
Case
"City"
Return
address.City
Case
"Postal Code"
Return
address.PostalCode
Case
"Province"
Return
address.Province
Case
"Country"
Return
address.Country
Case
Else
Return
"Huh?"
End
Select
End
Function
End
Class
End
Namespace
Public
Class
Landmark
Public
Property
Name
As
String
Public
Property
AddressId
As
Integer
End
Class
Public
Class
Address
Public
Property
Id
As
Integer
Public
Property
Street
As
String
Public
Property
City
As
String
Public
Property
Province
As
String
Public
Property
PostalCode
As
String
Public
Property
Country
As
String
End
Class