There is a certain data set which to a datagrid. Here everything is ok. But there was a need to sort the rows in this grid by a specific column. for example, in ascending order, sort the records with the price, BUT, starting from the 2nd line. Those. The first row must be fixed, and all other rows starting from the 2nd row must be sorted. If it were not for the condition that from the second line, then everything is simple:

Grid1.Sort(Поле,Порядок сортировки (asc,desc)); 

But how to do with the condition, I can not understand.

  • Write a custom comparator. And since the binding is used, you need to sort the data source. - Alexander Petrov

1 answer 1

work example

This is a view

 public partial class MainView : Form, IMainView { private BindingSource _bsPeople = new BindingSource(); public MainView() { InitializeComponent(); SetBindings(); this.CenterToScreen(); this.Text = nameof(WFApp1); } /// <summary> /// Привязки /// </summary> private void SetBindings() { _dataGridViewPeople.AutoGenerateColumns = false; _dataGridViewPeople.DataSource = _bsPeople; } /// <summary> /// Список людей /// </summary> public List<Person> People { get => _bsPeople.List.Cast<Person>().ToList(); set { _bsPeople.Clear(); foreach (var item in value) { _bsPeople.Add(item); } } } /// <summary> /// Привязка к событию клика по названию столбца /// </summary> private IFormsEventHandler<string> _SortPeople; public IFormsEventHandler<string> SortPeople { set { if (_SortPeople != null) return; _SortPeople = value; _dataGridViewPeople.ColumnHeaderMouseClick += (s, e) => { if (_bsPeople.Count == 0) return; if (e.ColumnIndex == 0) return; //клик по "н/п" //получаем название свойства по названю столбца string cName = GetColumnName(e.ColumnIndex); if (String.IsNullOrEmpty(cName)) return; //вызов обработчика _SortPeople.Handler(s, cName); }; } } private string GetColumnName(int columnIndex) { string result = String.Empty; switch (columnIndex) { case 1: result = nameof(ColumnLastName).Replace("Column", ""); break; case 2: result = nameof(ColumnFirstName).Replace("Column", ""); ; break; case 3: result = nameof(ColumnCity).Replace("Column", ""); ; break; default: break; } return result; } } 

This is a presenter

 public class MainPresenter : IMainPresenter { public IMainView View { get; private set; } //ctor public MainPresenter(IMainView view) { View = view ?? throw new ArgumentNullException(nameof(view)); View.SortPeople = new ParamEventHandler(OnSortPeople); LoadData(); } /// <summary> /// Обработка события клика по столбцу, сортировка /// </summary> /// <param name="columnName">имя столбца-свойства</param> public void OnSortPeople(string columnName) { //запоминаем первого (первая строка в гриде) var firstPerson = View.People.First(); //получаем данные и сортируем, в реальности сортировку можно //сделать и с помощью соотв.запроса к БД var people = Program.Context.GetPeople(); people.Sort(new PersonComparer(columnName)); //находим такого же и удаляем var samePerson = people.Single(p => p.Id == firstPerson.Id); people.RemoveAt(people.IndexOf(samePerson)); //новая коллекция var nPeople = new List<Person>(); //добавляем первого nPeople.Add(firstPerson); //добавляем остальных отсортированных nPeople.AddRange(people); //пронумеруем SetOrderNumbers(nPeople); //отобразим View.People = nPeople; } private void LoadData() { var people = Program.Context.GetPeople(); //пронумеруем SetOrderNumbers(people); //отобразим View.People = people; } private void SetOrderNumbers(List<Person> people) { for (int i = 1; i < people.Count + 1; i++) { people[i - 1].OrderNumber = i; } } } 

Custom comparator such

 public class PersonComparer : IComparer<Person> { private readonly string _propName; //ctor public PersonComparer(string propName) { if (String.IsNullOrEmpty(propName)) throw new ArgumentNullException(nameof(propName)); _propName = propName; } public int Compare(Person x, Person y) { int result = 0; switch (_propName) { case "FirstName": result = x.FirstName.CompareTo(y.FirstName); break; case "LastName": result = x.LastName.CompareTo(y.LastName); break; case "City": result = x.City.CompareTo(y.City); break; default: break; } return result; } } 

The whole example can be downloaded here.