| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Delphi: Базы данных и репортинг > DataModule & MDI |
| Автор: santilaas 30.4.2006, 07:54 | ||||
| Firebird1.5, FibPlus5.2 У меня такой вопрос: Создаю MDI - приложение. Имеется форма Main (fsMDIForm), форма Child (fsMDIChild) и DataModule (на нём есть DataSet и связанный с ним DataSource). Притом форма Child создаётся динамически (в опциях проекта она находится в столбце "Доступные формы") и открывается из главной формы следующим образом:
На форме Child имеется DBGridEh (связанный с DataSource) и поле Memo. Да, и кстати DataSet активизирую при событии OnCreate формы Child. Мне нужно, чтобы при переходе по записям в DBGridEh-е в поле Memo отображалось текущее значение. Для этого я в DataModule на события OnDataChange и OnStateChange (компонента DataSource) пишу одинаковый код:
Компилирую, запускаю, открываю эту форму и ... ошибка адреса ("Read of address 00000350"). Когда запускаю этот откомпилированный exe-шник, опять же выводится сообщение об ошибке - я его закрываю и все работает как надо (при переходе по записям все изменения-перемещения ображаются в Memo). Что интересно: если при таком же раскладе помещаю Child в опциях проекта в столбец "Автоматически создавать", то все работает, но эта дочерняя форма открывается вместе с Main формой - что совсем не то, что мне нужно. Помогите, люди добрые, что не так???? Мож чего дописать в обработчиках OnDataChange и OnStateChange???? Заранее спасибо, всем, даже тем кто все это прочитает! |
| Автор: santilaas 30.4.2006, 14:16 |
| Vas, когда активирую Датасет в onShow ситуация такая же - ошибка адреса. А насчет inherited - можно поподробнее, плз - что за строку надо ставить впереди? |
| Автор: Vas 1.5.2006, 07:03 |
В этом коде Child.Show убери для MDI-окон это не надо, еси MDI-окно создано то оно автоматически становится видимым. А строчка inherited в onCreate позволяет сначала выполнить свой код компоненту, а только потом выполнять то что написано после этой строки в конструкторе. |
| Автор: santilaas 1.5.2006, 08:04 | ||
| Vas, это снова я При создании дочерней формы пишу:
|
| Автор: Vas 1.5.2006, 13:28 | ||||
Ну все верно! Странно что ошибка лезет, а отладчиком не пробовал ее отловить? Попробуй еще заменить Memo на DBMemo ну и связать его с твоим DataSet'ом как полагается. Просто очень странно что когда форма создается автоматом ошибки нет, а когда не автоматом есть |
| Автор: santilaas 3.5.2006, 13:56 | ||
| В общем эта проблема решена (благодаря одному очень хорошему человеку): надо просто открывать дочернюю форму следующим образом:
НО!!! Тут возникла другая проблема - данные в ДБГриде появляются с некоторой задержкой. Я пробовал в этом коде (см. выше) поменять строки местами (т.е сначала активизирую DataSet, а затем делаю Create) и всё стало нормально для всех форм (у меня их много), кроме той (Child), она при таком раскладе выдаёт всё ту же ошибку адреса. Меняю строки обратно - все нормально, но ... тормоза при открытии. В чём проблема - вернее как её решить???? |
| Автор: vv3 5.5.2006, 23:36 | ||
Ну, когда ты делаешь это до TChild.Create, то ошибка будет, как ни крути, поскольку Child'a еще нету... "Тормоза при открытии", как подсказывает логика, возникают не за счет указанного порядка. Просто запрос отрабатывает долго. Вариант решения: попробуй вынести заполнение Memo в обработчик DataSet.AfterScroll, а заодно и Child.Create туда же:
|
| Автор: santilaas 14.5.2006, 10:31 | ||||||||||
- так то оно - так, но после этого проблемы с адресом как оказалось - остались. И таперь я их окончательно решил: просто нужно было (с моей стороны) быть внимательнее с переносом форм из автоматических в доступные, а насчет торможения вывода данных при открытии формы - vv3, ты был прав - это связано с самим запросом - долго выполняется). НО!!! Новая проблема или не совсем проблема, но в любом случае меня это не устраивает: Обрисую ситуацию заново: Есть форма - на ней 2 таблицы (мастер (DataSet1, DataSource1, DBGridEh1) и деталь(DataSet2, DataSource2, DBGridEh2) - она, кстати, открывается при нажатии на кнопку "Деталь") и поле Memo, в которое должно выводиться значение, заданное в onDataChange для той таблицы, на которой указатель. в onDataChange мастер таблицы пишу:
в onDataChange деталь таблицы пишу:
При нажатии на кнопку "Деталь" устанавливаю фокус на DBGridEh2:
А проблема в том, что, если я в данный момент нахожусь на DBGridEh1(т.е мастер-таблице) и скроллингом перемещаюсь по записям, то в поле Memo мелькают названия и из детал-таблицы. Например, в мастер таблице две записи: "Полка1" (для неё в деталь деталь - таблице: "Книга1","Книга2","Книга3") и "Полка2". Когда я в мастер-таблице при скроллинге попадаю на запись "Полка1", у меня в Memo отображается "Полка1", но чисто визуально может мелькнуть и "Полка1/Книга1". Как этого избежать??? |
| Автор: vv3 14.5.2006, 19:57 | ||
|
| Автор: santilaas 15.5.2006, 11:17 | ||||
| vv3, попробовал я - покрутил и так и этак, но вот какая ерунда. Делаю, так: 1 случай
- в мастер таблице как раз выводится то, что мелькает!!! При том тут вообще, если отскроллить ДБГрид до конца, ничего не мелькает, но колом встает DBGridEh2. 2 случай Если так:
и только - то в мастер таблице все как надо (ничего не мелькает), но при переходе в DBGridEh2, скроллирование в нём не работает (и вообще все колом)!!! Если в этом же случае при нажатии на кнопку, показывающую DBGridEh2, пишу: DetailDataset.EnableControls; - все та же ненормальная ситуация Уже пробовал что-нибудь сделать с событием onEndScroll - безрезультатно Но чувствую - истина где-то рядом - но где? |
| Автор: vv3 15.5.2006, 17:13 |
| А не пробовал вообще с другой стороны подойти - запихнуть Memo1.Lines.Add() в событие DbgridEh.OnEnter? |
| Автор: santilaas 16.5.2006, 11:03 | ||||
| Да, как я я и думал всё было ещё проще: у меня, как и говорил 2 DBGridEh-а (на форме кнопку нажимаешь - открывается один Grid, при этом у другого Grid-а Visible = False, другую кнопку нажимаешь - обратная ситуация). Короче на первую кнопку я написал:
На другую:
Короче получилось и без использования OnBeforeScroll и OnAfterScroll vv3, Спасибо большое, за помощь. У меня ещё маленький вопросик: DataSet-ы я активирую, когда открываю дочернюю форму, а деактивировать их при её закрытии надо? или необязательно? Вообще, как правильно? Или на моё усмотрение? |
| Автор: vv3 17.5.2006, 21:56 |
Именно, на твое усмотрение. У IBTransaction есть свойство taDefaultAction (что делать по умолчанию) и именно это она делает перед onDestroy... Если нужно особое поведение (я, например, при закрытии формы всегда опрашиваю состояние датасета и, если он редактировался, выдаю в TForm.onCloseQuery запрос на сохранение/отмену), то транзакцию можно откоммитить/отроллбэчить... Post/Cancel делать необязательно. |
| Автор: santilaas 20.5.2006, 17:30 |
| Понял. vv3, ещё раз спасибо за помощь |