Components for Delphi and C++ Builder.

Перейти в английский форум
Перейти на EhLib.com
Текущее время: 28 мар 2024, 16:10

Часовой пояс: UTC




Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: TDBGridEh - небольшие недоработки
СообщениеДобавлено: 17 дек 2019, 18:34 
Не в сети

Зарегистрирован: 17 дек 2019, 16:44
Сообщений: 3
Здравствуйте.
Решил посмотреть новый EhLib, понравилось, достойно. Но в пробной реализации выявились некоторые недостатки TDBGridEh.

1. SearchPanel с настройками по умолчанию. Проблема DataSet - OnScroll
1.1 При поиске многократно срабатывает GridEh.DataSource.DataSet.AfterScroll. Вместо того, чтобы сработать 1 раз - если в результате поиска позиция изменилась.
1.2 Вторая проблема Scroll'а. GridEh.DataSource.DataSet.AfterScroll - на этом событии, например, изменяются контролы формы.
Тогда, если в гриде в SearchPanel введен текст и нажатат фильтр, то при закрытии формы получаем AV. Т.к. в этот момент контролы формы уже освобождены, а AfterScroll еще вызывается.

2. DBGridEh в режиме дерева (+ ShowRowselCheckboxes).
Есть цикл обхода выделенных строк:
Код:
  for i:= 0 to dbgCondPPE.SelectedRows.Count - 1 do
     Обращение к dbgCondPPE.SelectedRows[i];

Выбираем все записи (для простоты), сворачиваем группы дерева. Запускаем цикл. И получаем в цикле - выход за границы массива.
Быть может, стоит в dbgCondPPE.SelectedRows хранить все выбранные строки, а например, в dbgCondPPE.VisibleSelectedRows хранить видимые.


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: TDBGridEh - небольшие недоработки
СообщениеДобавлено: 21 дек 2019, 23:38 
Не в сети

Зарегистрирован: 21 дек 2011, 18:48
Сообщений: 1546
Добрый день.

Цитата:
1. SearchPanel с настройками по умолчанию. Проблема DataSet - OnScroll
1.1 При поиске многократно срабатывает GridEh.DataSource.DataSet.AfterScroll. Вместо того, чтобы сработать 1 раз - если в результате поиска позиция изменилась.

В DataSet к сожалению, нельзя проверить значение ячейки (и проверить что она удовлетворяет тексту в SearchPanel) в каждой записи без перехода на каждую запись.

Цитата:
1.2 Вторая проблема Scroll'а. GridEh.DataSource.DataSet.AfterScroll - на этом событии, например, изменяются контролы формы.
Тогда, если в гриде в SearchPanel введен текст и нажатат фильтр, то при закрытии формы получаем AV. Т.к. в этот момент контролы формы уже освобождены, а AfterScroll еще вызывается.

Попробуйте в событии FormClose устанавливать флаг указывающий, что формы уже закрыта и не проверять контролы в AfterScroll.

Цитата:
DBGridEh в режиме дерева (+ ShowRowselCheckboxes).
Есть цикл обхода выделенных строк:

На тестовом проекте ошибка не воспроизводиться.
Событие
Код:
[code][/code]procedure TForm1.Button4Click(Sender: TObject);
var
  i: Integer;
  Item: TUniBookmarkEh;
begin
  for i:= 0 to DBGridEh1.SelectedRows.Count - 1 do
  begin
    Item := DBGridEh1.SelectedRows[i];
  end;
end;

обрабатывается без ошибок, если выбрать все записи в гриде и свернуть несколько узлов
Напишите, пожалуйста, более точно, какой код вы используете.

_________________
Best regards
EhLib support Team


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: TDBGridEh - небольшие недоработки
СообщениеДобавлено: 22 дек 2019, 14:59 
Не в сети

Зарегистрирован: 17 дек 2019, 16:44
Сообщений: 3
1)
Цитата:
В DataSet к сожалению, нельзя проверить значение ячейки (и проверить что она удовлетворяет тексту в SearchPanel) в каждой записи без перехода на каждую запись.

Я понимаю, что вам приходится перемещаться по записям. Я как раз и имею в виду, почему бы до окончания этого поиска не отключать пользовательские события DataSet.BeforeScroll и DataSet.AfterScroll? Это было бы логично и правильно.
Иначе, я не нахожу ни одного адекватного способа определить окончание поиска и последнее перемещение, чтобы однократно выполнить на AfterScroll достаточно емкую обработку.

2)
Цитата:
Попробуйте в событии FormClose устанавливать флаг указывающий, что формы уже закрыта и не проверять контролы в AfterScroll.

Как обойти ошибку я знаю, мне даже проще проверять 1-й проверяемый контрол на равенство nil. Я понимаю, что в принципе, это не вина библиотеки. Но, может быть, вы можете рассмотреть вариант проверки состояния формы - и если она на стадии закрытия/освобождения, то отключить пользовательские события для DataSet при сбросе фильтра SearchPanel, т.к. они все равно не имеют смысла.

3)
Цитата:
Выбираем все записи (для простоты), сворачиваем группы дерева. Запускаем цикл. И получаем в цикле - выход за границы массива.
Быть может, стоит в dbgCondPPE.SelectedRows хранить все выбранные строки, а например, в dbgCondPPE.VisibleSelectedRows хранить видимые.

Прошу прощения, воспроизводил по памяти. Конечно же не совсем верно описал ситуацию.
Код:
  for i:= 0 to dbg1.SelectedRows.Count - 1 do begin
    dbg1.DataSource.DataSet.Bookmark := dbg1.SelectedRows[i];
  end;

Там ошибка DataSet - record not found. Прикрепил на всякий случай проект. С гридом все нормально.
Если я правильно понимаю, то при сворачивании узла DataSet фильтруется? Если так, то последний вопрос снимается.
Варианты решения проблемы я знаю. Извиняюсь за беспокойство.


Вложения:
EhLib_Tree.zip [54.84 KiB]
Скачиваний: 70
Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: TDBGridEh - небольшие недоработки
СообщениеДобавлено: 23 дек 2019, 07:20 
Не в сети

Зарегистрирован: 21 дек 2011, 18:48
Сообщений: 1546
Добрый день.

1
Цитата:
Я понимаю, что вам приходится перемещаться по записям. Я как раз и имею в виду, почему бы до окончания этого поиска не отключать пользовательские события DataSet.BeforeScroll и DataSet.AfterScroll? Это было бы логично и правильно.

Грид отключает события в цепочки DataSource-Dataset используя стандартный метод отключения событий DisableControls. Но события DataSet.Before… и DataSet.After… являются неотключаемыми. Предполагается что разработчик должен использовать эти события, когда нужны события, которые будут вызываться всегда, при любом перемещении по DataSet'у, в любом режиме.

Цитата:
Иначе, я не нахожу ни одного адекватного способа определить окончание поиска и последнее перемещение, чтобы однократно выполнить на AfterScroll достаточно емкую обработку.

Можно предложить несколько вариантов решения.
1.1 Перенести логику выполнения операции на изменение текущей записи в отключаемое событие DataSource.OnDataChange
1.2 Написать свою версию поиска, и в ней отключать нужные события.
Вызов поиска проходит через виртуальный метод TDBGridEhCenter.DefaultLocateText
Вы можете написать свой класс TMyDBGridEhCenter и зарегистрировать его как класс используемый для всех гридов проекта.


Код:
type
  TMyDBGridEhCenter = class(TDBGridEhCenter)
    function DefaultLocateText(AGrid: TCustomDBGridEh; const FieldName: string; const Text: String; Options: TLocateTextOptionsEh; Direction: TLocateTextDirectionEh; Matching: TLocateTextMatchingEh; TreeFindRange: TLocateTextTreeFindRangeEh; TimeOut: LongWord = 0; CheckValueEvent: TCheckColumnValueAcceptEventEh = nil): Boolean; override;
  end;

{ TMyDBGridEhCenter }

function TMyDBGridEhCenter.DefaultLocateText(AGrid: TCustomDBGridEh;
  const FieldName, Text: String; Options: TLocateTextOptionsEh;
  Direction: TLocateTextDirectionEh; Matching: TLocateTextMatchingEh;
  TreeFindRange: TLocateTextTreeFindRangeEh; TimeOut: LongWord;
  CheckValueEvent: TCheckColumnValueAcceptEventEh): Boolean;
var
  OldAfterScroll: TDataSetNotifyEvent;
begin
  OldAfterScroll := AGrid.DataSource.DataSet.AfterScroll;
  AGrid.DataSource.DataSet.AfterScroll := nil;
  Result := inherited DefaultLocateText(AGrid, FieldName, Text,
    Options, Direction, Matching, TreeFindRange, TimeOut, CheckValueEvent);
  AGrid.DataSource.DataSet.AfterScroll := OldAfterScroll;
end;

initialization
  SetDBGridEhCenter(TMyDBGridEhCenter.Create);
end.


2.
Цитата:
Как обойти ошибку я знаю, мне даже проще проверять 1-й проверяемый контрол на равенство nil. Я понимаю, что в принципе, это не вина библиотеки.

Наверно контрол на форме не должен отключать все или часть событий в других контролов когда он это считает нужным, иначе он может просто сломать логику работы формы в части уже написанных приложений.

3.
Цитата:
Если я правильно понимаю, то при сворачивании узла DataSet фильтруется?

Именно так. Сворачиваемые записи скрываются в гриде с помощью стандартного механизма фильтрации.
Переход на отфильтрованную запись простым способом невозможен.

_________________
Best regards
EhLib support Team


Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: TDBGridEh - небольшие недоработки
СообщениеДобавлено: 24 дек 2019, 03:37 
Не в сети

Зарегистрирован: 16 фев 2018, 04:13
Сообщений: 54
Откуда: АО ОТЭКО
Я для целей получения события изменения активной строки после остановки поиска написал маленький компонент. Работает по тому же принципу что Master - Detail, событие срабатывает один раз.


Вложения:
TMyDataLink.zip [11.9 KiB]
Скачиваний: 75
Вернуться наверх
 Профиль  
 
 Заголовок сообщения: Re: TDBGridEh - небольшие недоработки
СообщениеДобавлено: 31 дек 2019, 14:43 
Не в сети

Зарегистрирован: 17 дек 2019, 16:44
Сообщений: 3
istrebitel писал(а):
Я для целей получения события изменения активной строки после остановки поиска написал маленький компонент. Работает по тому же принципу что Master - Detail, событие срабатывает один раз.

тоже вариант, хоть конечно более замороченный)) спасибо!

Цитата:
Грид отключает события в цепочки DataSource-Dataset используя стандартный метод отключения событий DisableControls. Но события DataSet.Before… и DataSet.After… являются неотключаемыми. Предполагается что разработчик должен использовать эти события, когда нужны события, которые будут вызываться всегда, при любом перемещении по DataSet'у, в любом режиме.
Можно предложить несколько вариантов решения.
1.1 Перенести логику выполнения операции на изменение текущей записи в отключаемое событие DataSource.OnDataChange
1.2 Написать свою версию поиска, и в ней отключать нужные события.
Вызов поиска проходит через виртуальный метод TDBGridEhCenter.DefaultLocateText
Вы можете написать свой класс TMyDBGridEhCenter и зарегистрировать его как класс используемый для всех гридов проекта.


Цитата:
Наверно контрол на форме не должен отключать все или часть событий в других контролов когда он это считает нужным, иначе он может просто сломать логику работы формы в части уже написанных приложений.


Спасибо! Событие OnDataChange в данном случае подходит. Кстати, оно же решает и проблему 2.
На счет событий DataSet.Before… и DataSet.After - на мой взгляд в данном случае, при поиске, эти срабатывания являются "мусорными" и разве что пригодятся при отладке.
Можно было бы добавить свойство для SearchPanel (что-то вроде DisableScrollsWhenSearching), которое при отключении включало бы эти события. Хоть у DataSet и есть своя логика, но она не подходит, по моему мнению, под все случаи.
Предлагаю подумать над доп. свойством, чтобы эта проблема была управляемой. Как минимум AV на выше описанных событиях (...scroll) при стандартном Create-ShowModal-Free формы уже говорит, что логика не покрывает 100% случаев.
В любом случае, огромное спасибо! Тех.поддержка EhLib великолепна!
С наступающим Новым годом, товарищи!

upd:
Все-таки OnDataChange не подходит для всех ситуаций - например, когда данные редактируются в гриде. Т.к. событие вызывается и при любом изменении данных. А городить каждый раз огород с переопределением центра или тем более созданием доп. компонентов муторно.
Поэтому, как пожелание, которое думаю всем бы в дальнейшем помогло - добавить свойство для SearchPanel, описанное чуть выше.


Вернуться наверх
 Профиль  
 
Показать сообщения за:  Сортировать по:  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC


Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 5


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB