Programmatically sort multiple columns

7 posts, 2 answers
  1. Andy
    Andy avatar
    25 posts
    Member since:
    Jan 2011

    Posted 22 Mar 2011 Link to this post

    Hi, basically I want to simulate the Shift + click to sort multiple columns. For example, if the user click on Column A to do an ascending sort, I want to also sort Column B ascending.
    I added the sort descriptors in the designer and it works on startup, but as soon I click on Column A or B, the original sort descriptors are lost.
    Any suggestions?

    Thanks,
    Andy
  2. Answer
    Emanuel Varga
    Emanuel Varga avatar
    1336 posts
    Member since:
    May 2010

    Posted 25 Mar 2011 Link to this post

    Hello Andy,

    There is no easy way to do this, but this example will do everything you need:
    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using Telerik.WinControls.Data;
    using Telerik.WinControls.UI;
     
    public partial class Form1 : Form
    {
        private RadGridView radGridView1;
        private List<Person> persons;
     
        public Form1()
        {
            InitializeComponent();
            this.Controls.Add(radGridView1 = new RadGridView());
            radGridView1.Dock = DockStyle.Fill;
            radGridView1.AutoSizeColumnsMode = GridViewAutoSizeColumnsMode.Fill;
            radGridView1.GridBehavior = new CustomGridBehavior();
     
            persons = new List<Person>();
     
            for (int i = 0; i < 20; i++)
            {
                if (i % 4 == 0)
                {
                    persons.Add(new Person
                    {
                        Id = i,
                        Name = "L'Person " + i,
                    });
                }
                else
                {
                    persons.Add(new Person
                    {
                        Id = i,
                        Name = "Person " + i,
                    });
                }
            }
     
            radGridView1.DataSource = persons;
        }
     
        private class CustomGridBehavior : BaseGridBehavior
        {
            public override bool OnMouseDown(MouseEventArgs e)
            {
                var cell = this.GridControl.ElementTree.GetElementAtPoint(e.Location) as GridHeaderCellElement;
                if (cell != null)
                {
                    Keyboard.HoldShift();
                }
     
                return base.OnMouseDown(e);
            }
     
            public override bool OnMouseUp(MouseEventArgs e)
            {
                if (Keyboard.ShiftPressed)
                {
                    Keyboard.ReleaseShift();
                }
     
                return base.OnMouseUp(e);
            }
     
            public override bool ProcessKeyPress(KeyPressEventArgs keys)
            {
                if (keys.KeyChar == (char)Keys.Space)
                {
                    if (this.GridControl.CurrentRow != null && this.GridControl.CurrentRow.DataBoundItem != null)
                    {
                        var data = this.GridControl.CurrentRow.DataBoundItem as Person;
                        if (data != null)
                        {
                            data.Selected = !data.Selected;
                            this.GridControl.CurrentRow.InvalidateRow();
                        }
                    }
                }
     
                return base.ProcessKeyPress(keys);
            }
        }
     
        private static class Keyboard
        {
            const int VK_SHIFT = 0x10;
            const uint KEYEVENTF_KEYUP = 0x2;
            static bool shiftPressed = false;
     
            public static bool ShiftPressed
            {
                get
                {
                    return Keyboard.shiftPressed;
                }
            }
     
            [DllImport("user32.dll")]
            public static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, uint dwExtraInfo);
     
            public static void HoldShift()
            {
                if (!shiftPressed)
                {
                    keybd_event((byte)VK_SHIFT, 0, 0, 0);
                    shiftPressed = true;
                }
            }
     
            public static void ReleaseShift()
            {
                if (shiftPressed)
                {
                    keybd_event((byte)VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
                    shiftPressed = false;
                }
            }
        }
    }
     
    public class Person
    {
        public int Id
        {
            get;
            set;
        }
     
        public string Name
        {
            get;
            set;
        }
     
        public bool Selected
        {
            get;
            set;
        }
    }

    Hope this helps, if you have any other questions or comments, please let me know,

    Best Regards,
    Emanuel Varga
    Telerik WinForms MVP
  3. Answer
    Jack
    Admin
    Jack avatar
    2333 posts

    Posted 25 Mar 2011 Link to this post

    Hello Andy,

    Thank you for this question. You can use the SortOrder property of GridViewDataColumn to simulate the Shift key. Here is an example:
    this.radGridView1.Columns[0].SortOrder = RadSortOrder.Ascending;
    this.radGridView1.Columns[1].SortOrder = RadSortOrder.Descending;

    I hope this helps. If you have further questions, do not hesitate to write us.

    All the best,
    Jack
    the Telerik team
  4. Andy
    Andy avatar
    25 posts
    Member since:
    Jan 2011

    Posted 25 Mar 2011 Link to this post

    Emanuel, thank you very much for your sample code. It's very close to what I need, and shows new information about the grid that I didn't know before.

    Jack, your solution works. I just have to figure out which events to change the sort order. I'm currently using MouseDown to trap the column sorting event, and change the other column SortOrder on MouseUp.

    Andy
  5. Jack
    Admin
    Jack avatar
    2333 posts

    Posted 30 Mar 2011 Link to this post

    Hello Andy,

    Thank you for writing us back. You can handle the SortChanged event in this case. Please consider the following code:
    void radGridView1_SortChanged(object sender, GridViewCollectionChangedEventArgs e)
    {
        if (this.radGridView1.SortDescriptors.Contains("City"))
        {
            this.radGridView1.Columns["Country"].SortOrder = this.radGridView1.Columns["City"].SortOrder;
        }
        else
        {
            this.radGridView1.Columns["Country"].SortOrder = RadSortOrder.None;
        }           
    }

    Regards,

    Jack
    the Telerik team
  6. pawan
    pawan avatar
    5 posts
    Member since:
    Jul 2011

    Posted 22 Dec 2016 in reply to Jack Link to this post

    I have the same requirement for Kendo UI Grid.

    Any suggestion, please.

  7. Dess | Tech Support Engineer, Sr.
    Admin
    Dess | Tech Support Engineer, Sr.  avatar
    4086 posts

    Posted 22 Dec 2016 Link to this post

    Hello Pawan,

    Thank you for writing.  

    I would like to note that this forum is related to the Telerik UI for WinForms suite. If you have any questions regarding other Telerik products, feel free to post your queries in the relevant forum: http://www.telerik.com/forums

    Thank you for your understanding.

    Regards,
    Dess
    Telerik by Progress
    Try our brand new, jQuery-free Angular 2 components built from ground-up which deliver the business app essential building blocks - a grid component, data visualization (charts) and form elements.
Back to Top