I need to use custom (server-side) sorting in RadGridView, and I am almost there. I have followed the code examples I found here in the forum and come up with something like the code below (highly simplified example). The problem is, that when I set e.Cancel = true in the RadGridView_Sorting event handler, the sorting indicators disappear from the column headers once the data is returned from the server. I have come up with a work-around (commented out in the example) where I manually set the SortingDescriptors property to the correct value _after_ the data is returned, but should I really need to do that? Everything works fine if I avoid setting e.Cancel to true, but then there will be two sorting operations, first the client-side (incorrectly sorted of course) and then when the wcf call returns the data will be correctly sorted. Is this a bug, or do I have to stick with my ugly work-around?
XAML:
C#:
/Henrik
XAML:
<UserControl x:Class="TestApp02.ListUsers02" |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls" |
xmlns:teleriknav="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Navigation" |
xmlns:gv="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView" |
xmlns:gv2="clr-namespace:Telerik.Windows.Controls.GridView;assembly=Telerik.Windows.Controls.GridView" |
xmlns:data="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Data"> |
<Grid x:Name="LayoutRoot" |
Background="White"> |
<gv:RadGridView x:Name="RadGridView1" |
IsFilteringAllowed="False" |
MultipleSelect="True" |
RowIndicatorVisibility="Collapsed" |
ShowGroupPanel="False" |
AutoGenerateColumns="False"> |
<gv:RadGridView.Columns> |
<gv:GridViewSelectColumn Width="50"></gv:GridViewSelectColumn> |
<gv:GridViewDataColumn Header="ID" |
IsCustomSortingEnabled="True" |
IsReadOnly="True" |
DataMemberBinding="{Binding ID}"> |
</gv:GridViewDataColumn> |
<gv:GridViewDataColumn Header="Age" |
IsCustomSortingEnabled="True" |
IsReadOnly="True" |
DataMemberBinding="{Binding Age}"> |
</gv:GridViewDataColumn> |
<gv:GridViewDataColumn Header="Name" |
IsCustomSortingEnabled="True" |
IsReadOnly="True" |
DataMemberBinding="{Binding Name}"> |
</gv:GridViewDataColumn> |
</gv:RadGridView.Columns> |
</gv:RadGridView> |
</Grid> |
</UserControl> |
C#:
using System; |
using System.Collections.Generic; |
using System.Linq; |
using System.Net; |
using System.Windows; |
using System.Windows.Controls; |
using System.Windows.Documents; |
using System.Windows.Input; |
using System.Windows.Media; |
using System.Windows.Media.Animation; |
using System.Windows.Shapes; |
using Telerik.Windows.Controls; |
using Telerik.Windows.Data; |
using System.ComponentModel; |
using System.Windows.Threading; |
namespace TestApp02 |
{ |
public partial class ListUsers02 : UserControl |
{ |
public ListUsers02() |
{ |
InitializeComponent(); |
Dispatcher.BeginInvoke(Initialized); |
} |
private void Initialized() |
{ |
RadGridView1.Sorting += RadGridView1_Sorting; |
LoadPeople("Name", true); |
} |
void RadGridView1_Sorting(object sender, GridViewSortingEventArgs e) |
{ |
if (e.OldSortingState == SortingState.None) |
{ |
e.NewSortingState = SortingState.Ascending; |
LoadPeople(e.SortPropertyName, true); |
} |
else if (e.OldSortingState == SortingState.Ascending) |
{ |
e.NewSortingState = SortingState.Descending; |
LoadPeople(e.SortPropertyName, false); |
} |
else |
{ |
e.NewSortingState = SortingState.None; |
LoadPeople(e.SortPropertyName, true); |
} |
//If I remove this everything is ok, but then the data will be sorted twice |
e.Cancel = true; |
} |
private void LoadPeople(string sortPropertyName, bool ascending) |
{ |
//Using a timer to simulate async wcf call |
var timer = new DispatcherTimer(); |
timer.Tick += (s, e2) => |
{ |
timer.Stop(); |
var people = Person.GetSome(); |
if (ascending) |
{ |
if (sortPropertyName == "Name") |
{ |
RadGridView1.ItemsSource = people.OrderBy(person => person.Name).ToList(); |
} |
else if (sortPropertyName == "Age") |
{ |
RadGridView1.ItemsSource = people.OrderBy(person => person.Age).ToList(); |
} |
else if (sortPropertyName == "ID") |
{ |
RadGridView1.ItemsSource = people.OrderBy(person => person.ID).ToList(); |
} |
} |
else |
{ |
if (sortPropertyName == "Name") |
{ |
RadGridView1.ItemsSource = people.OrderByDescending(person => person.Name).ToList(); |
} |
else if (sortPropertyName == "Age") |
{ |
RadGridView1.ItemsSource = people.OrderByDescending(person => person.Age).ToList(); |
} |
else if (sortPropertyName == "ID") |
{ |
RadGridView1.ItemsSource = people.OrderByDescending(person => person.ID).ToList(); |
} |
} |
//If I enable this, it works, but I think I shouldn't have to |
//SetSortDescriptors(sortPropertyName, ascending); |
}; |
//Simulating 0.5 second server call |
timer.Interval = new TimeSpan(0, 0, 0, 0, 500); |
timer.Start(); |
} |
private void SetSortDescriptors(string sortPropertyName, bool ascending) |
{ |
RadGridView1.SortDescriptors.Clear(); |
var sort = new SortDescriptor(); |
sort.Member = sortPropertyName; |
if (ascending) |
sort.SortDirection = ListSortDirection.Ascending; |
else |
sort.SortDirection = ListSortDirection.Descending; |
RadGridView1.SortDescriptors.Add(sort); |
} |
} |
public class Person |
{ |
public int ID { get; set; } |
public int Age { get; set; } |
public string Name { get; set; } |
public Person(int id, int age, string name) |
{ |
this.ID = id; |
this.Age = age; |
this.Name = name; |
} |
public static List<Person> GetSome() |
{ |
List<Person> people = new List<Person>(); |
people.Add(new Person(1, 45, "Ian")); |
people.Add(new Person(2, 17, "Betty")); |
people.Add(new Person(3, 34, "Marie")); |
people.Add(new Person(4, 65, "Carl")); |
people.Add(new Person(5, 56, "Anna")); |
people.Add(new Person(6, 35, "Jimmy")); |
return people; |
} |
} |
} |
/Henrik