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 OffOption Strict OnOption Explicit OnImports Telerik.Web.UIImports System.Web.HttpContextNamespace 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 ClassEnd NamespacePublic Class Landmark Public Property Name As String Public Property AddressId As IntegerEnd ClassPublic 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 StringEnd Class