Какое событитие предшествует применению сортировки?

Cat2
Дата: 16.04.2014 21:30:17
Есть задача. После применения сортировки колонки при SortMode типа "automatic" надо, что бы фокус на текущей записи в DataGridView не изменилась. По умолчанию, если ничего не делать, после сортировки неизменным остается свойство BindingSource.Position. То есть если стоял фокус на второй строке, так на второй строке он и останется.

В событии MouseHeaderClick BindingSource.Position устанавливается в ноль!

Как он потом, после ссортировке, устанавливается на позицию, предшествующую сортировке мне не удалось найти.
==============
При SortMode колонки типа "progammatic" все просто.

В событии "клик по заголовку" запоминаю значение ключевого поля, делаю сортировку и в событии Sorted перехожу к записи по значению запомненного ключевого поля.

Это-то просто, но надо программировать отрисовку глифов.
Да и черт с ним, это тоже решаемо. Но некоторые колонки надо сортировать особым способом - по скрытым колонкам. Опять писать обработчик для всех колонок с проверкой на особые случаи
Cat2
Дата: 18.04.2014 21:48:51
Не стал выпендриваться, сделал все через столбцы "programmatic"
RomanH
Дата: 19.04.2014 10:28:54
Cat2
Не стал выпендриваться, сделал все через столбцы "programmatic"

+1
тоже заюзал programmatic потому что сортирую грид по нескольким свойствам
Cat2
Дата: 19.04.2014 12:10:48
Решил мини-статью написать, об этой гребаной пользовательской сортировке в гриде.
Может кто-то мимо граблей пролетит.
Пишу на примере DataSet-DataTable. При использовании Linq для SQL у меня получились те же яйца, вид сбоку. Воможно я его плохо знаю. Пусть тогда знающие люди поправят.

Во-первых, сортировать можно в двух местах: в DataGridView и в BindingSource.

Во-вторых, есть разница между сортировкой в DataGridView с привязанным источником (DataSource) и гридом в виртуальном режиме – DataGridView (DataGridView.VirtualMode = true).
Когда элемент управления DataGridView привязывается к внешнему источнику данных, необходимо использовать операции сортировки, предоставляемые этим источником данных.
BindingSource этой возможности не предоставляет.
Хотя мне непонятно почему, ведь у него есть метод Sort!

В виртуальном режиме и если источник поддерживает сортировку, то все отлично. Можно использовать оба конструктора:
• Sort(IComparer) Сортирует содержимое элемента управления DataGridView, используя реализацию интерфейса IComparer.
• Sort(DataGridViewColumn, ListSortDirection) Сортирует содержимое элемента управления DataGridView по убыванию или по возрастанию, основываясь на содержимом указанного столбца.
Даже больше. Можно не возиться с написанием IComparer, а использовать событие DataGridView.onSortCompare. Причем Net сердцем чует, имеет ли источник возможность сортировки. Если нет, то в это событие просто не игнорируется .

Если совсем тяжко, то можно в качестве источника указать List<T>, но тогда надо будет писать множество нужных методов и событий. Я не рискнул лезть в эти дебри.

Итак, мы потеряли все плюшки от того, что используем грид с привязанным источником данных, не поддерживающим сортировки. Но надо что-то делать!

Единственный путь – создание специального столбца для сортировки в режиме Programmatic, и отлов нажатия левой ноги мыши на ColumnHeaderMouseClick.

И тут варианты. Я описываю только возникавшие у меня потребности.
1. Сортировка по нескольким полям. Тут все просто. Забываем про DataGridView и делаем что-то вроде: BindungSource.Sort=”Field0 Asc, Field1 Desc”. И все! Простая строка решает проблему.

2. Сортировка по полям типа DataGridViewComboBox. Создаем в DataTablе вычисляемое поле. Делаем связь (Relation) между родителем-справочником и дочкой – нашей главной таблице. Если делать не вручную, то эта связь получить название вроде “ParenTable_ChildTable”.
В поле Expession созданного столбца пишем что-то вроде Parent(ParenTable_ChildTable).FieldName.
Теперь можно применить Sort(DataGridViewColumn, ListSortDirection). Только DataGridViewColumn должно быть по созданному столбцу.

3. Сортировка по функции. Если удастся использовать допустимые функции ( http://msdn.microsoft.com/ru-ru/library/system.data.datacolumn.expression(v=vs.110).aspx ), то делаем по пункту 2. Например, по произведению двух полей - Количество*Цена.
Если нет, то есть два выхода, как минимум.
Для примера, задача. Сделать «истинную» сортировку IP-адресов. Что бы 10.2.0.0 шло раньше 10.100.0.0
Первый – возвратить из базы дополнительный столбец, с предрассчитанным и удобными для сортировки значениями. Для IP это будет примерно так: 010.002.000.000.
Второй – рассчитать этот столбец после загрузки. Какой способ выбрать – думать самому в разрезе производительности среднего клиентского компа, скорости сети и других параметров.
Не забыть сделать DataTable.AccetpChanges до того, как заработает обработчик RowChanged!
Оба этих способа не очень хороши, так как при изменении исходного поля надо вручную менять значение в «поле для сортировки»
Где-то в степи
Дата: 19.04.2014 13:13:23
Cat2,
не понятно, весь сыр бор из за этого?
автор
По умолчанию, если ничего не делать, после сортировки неизменным остается свойство BindingSource.Position. То есть если стоял фокус на второй строке, так на второй строке он и останется.

дак нативно он поддерживает что что вы просите...
Cat2
Дата: 19.04.2014 17:19:45
Где-то в степи
Cat2,
не понятно, весь сыр бор из за этого?
автор
По умолчанию, если ничего не делать, после сортировки неизменным остается свойство BindingSource.Position. То есть если стоял фокус на второй строке, так на второй строке он и останется.

дак нативно он поддерживает что что вы просите...

Что нативно поддерживает?