Delphi: связь между фреймами

Как общаться между фреймами и внутри фрейма? Например: кадр 1 и кадр 2.

Фрейм 2 находится в фрейме 1. Чтобы вставить фрейм 2 в фрейм 1, я добавляю фреймы из ToolPalette ->

type
  TFrame1 = class(TFrame)
  Frame22: TFrame2;

  var MyFrame1:TFrame1; // Now I can access to everything within a frame and from other frames too
implementation

Но у меня есть ошибка при попытке доступа к MyFrame1 и выполнения чего-то вроде MyFrame1.Button1.Enable в кадре 1 или из других кадров: «Класс исключения EAccessViolation с сообщением« Нарушение доступа по адресу 0084858C в модуле «P1.exe» »»

Как получить доступ к кадру 1 из кадра 2? MyFrame1-> Ошибка.

Спасибо!


person maxfax    schedule 18.07.2011    source источник


Ответы (2)


Удалите объявление глобальной переменной:

var MyFrame1: TFrame1;

Обычно это не имеет смысла для фреймов.

Вы можете привести тип Owner дочернего фрейма к TFrame1, например:

implementation

uses
  FrameUnit1;

procedure TFrame2.Test;
begin
  if Owner is TFrame1 then
    ShowMessage(TFrame1(Owner).Name);
end;
person Ondrej Kelle    schedule 18.07.2011
comment
@Embarcadero, пожалуйста, дайте мне возможность НЕ генерировать эти надоедливые глобальные вары. И пока вы это делаете, пожалуйста, прекратите добавлять новые формы в автоматически созданные списки форм проекта (эти два элемента связаны). Спасибо. И +1. - person Cosmin Prund; 18.07.2011
comment
Owner не может быть необъявленным идентификатором во фрейме, потому что он введен из TComponent. Вы уверены, что не ошиблись в написании? - person Cosmin Prund; 18.07.2011
comment
@Cosmin Tools - ›Параметры -› [Параметры среды + VCL Designer] - ›Автоматическое создание форм и модулей данных - person ain; 18.07.2011
comment
@TOndrej Разве Owner не всегда является корневой формой, а Parent - это оконный контейнер, содержащий элемент управления? Т.е. когда вы перетаскиваете frame1 на form1 и frame2 на frame1, владельцем frame2 будет form1, а Parent будет frame1. - person ain; 18.07.2011
comment
@ain Нет, это непосредственный владелец. В этом случае родительский фрейм TFrame1. - person Ondrej Kelle; 18.07.2011
comment
@ain, @TOndrej, если вы удалите Frame2 на Frame1 в редакторе Frame1, владельцем будет Frame1. Если вы поместите его на экземпляр Frame1 во время редактирования формы, владельцем должна быть форма. Я бы предпочел пройтись по родительскому списку, чтобы охватить обе ситуации. Или создайте фрейм из кода. - person Cosmin Prund; 18.07.2011
comment
@Cosmin Нет, владельцем будет экземпляр TFrame1, а не форма. - person Ondrej Kelle; 18.07.2011
comment
@TOndrej, результаты тестирования: если вы перетащите Frame2 на Frame1 во время редактирования формы, владельцем будет .. none. IDE Delphi не позволяет этого сделать. Единственный способ поместить Frame2 в Frame1 во время разработки - это добавить в редактор Frame1 или добавить его во время выполнения из кода. - person Cosmin Prund; 18.07.2011
comment
@Cosmin Извините, я сначала неправильно прочитал ваш комментарий. Если вы перетаскиваете экземпляр TFrame2 на экземпляр TFrame1 при редактировании формы, я думаю, что вы действительно удаляете его в форму. Если, однако, TFrame1 спроектирован так, чтобы содержать TFrame2 (что, как я считаю, имеет место здесь), тогда - когда вы отбрасываете экземпляр TFrame1 в форму, владельцем дочернего кадра (TFrame2) будет этот экземпляр TFrame1, а не корневая форма. - person Ondrej Kelle; 18.07.2011
comment
@ain, @TOndrej: родительский элемент для Frame2 - это Frame1, но форма, вероятно, является владельцем обоих. Таким образом, OP должен использовать Родителя, а не Владельца. - person Rudy Velthuis; 18.07.2011
comment
@Rudy Извините, но это не так, попробуйте и убедитесь сами. - person Ondrej Kelle; 18.07.2011
comment
Я не могу попробовать прямо сейчас (я нахожусь в своей клинике), но я уверен, что родительский элемент - это TFrame1, поскольку на нем был установлен TFrame2. Если вы используете parent, не имеет значения, является ли владельцем другой фрейм или форма. - person Rudy Velthuis; 18.07.2011
comment
@TOndrej: если Frame1 предназначен для содержания TFrame2, тогда TFrame1 также будет родительским. Если TFrame1 не предназначен для хранения Tframe2, но добавляется к нему при редактировании формы, тогда что является родительским, а что - владельцем? Вероятно, форма в обоих случаях. - person Rudy Velthuis; 18.07.2011
comment
В этом случае лучше использовать Parent (какой бы он ни был) и перебирать его свойство Controls, чтобы найти TFrame2 (при условии, что он только один). - person Rudy Velthuis; 18.07.2011
comment
Я создал два фрейма, превратил их в шаблоны и поместил оба в форму. Владелец и Родитель каждого из них были формой. Теперь я отбросил TFrame2Template на TFrame1, а владельцем и родительским элементом TFrame2 был TFrame1. Так что на самом деле не имеет значения, используете ли вы Parent или Owner. - person Rudy Velthuis; 18.07.2011
comment
@Rudy Я согласен, важно использовать то, что вам подходит. ;-) - person Ondrej Kelle; 18.07.2011

TOndrej упомянул об использовании Owner, но обычно это форма, а не Frame1. Родителем Frame2 должен быть Frame1, поэтому:

uses
  Frame1Unit;

procedure TFrame2.Test;
var
  C: TControl;
begin
  if Parent is TFrame1 then
    ShowMessage(TFrame1(Parent).Name)
  else 
    for C in Parent.Controls do
      if C is TFrame1 then
        ShowMessage(TFrame1(C).Name);
end; 

Обновлен: добавлен код для использования Parent.Controls для поиска TFrame1.

person Rudy Velthuis    schedule 18.07.2011
comment
Во время разработки при редактировании формы вы не можете разместить Frame2 на Frame1, чтобы Frame1 был родительским для Frame2. Попробуйте сами в IDE. Даже если кажется, что Frame2 является родительским элементом Frame1, перетащите его, и вы увидите, что он фактически является родительским элементом формы. Если вы отбрасываете Frame2 на Frame1 в редакторе Frame1, то гарантируется, что владельцем Frame2 является Frame1. Как сказал вам TOndrej, попробуйте, и вы увидите. Непосредственный Родитель с гораздо меньшей вероятностью будет принадлежать к типу TFrame1: Родитель вполне может быть TScrollBox или TPanel, который, в свою очередь, является родителем TFrame1. - person Cosmin Prund; 18.07.2011
comment
Не могу проверить это прямо сейчас, так как нахожусь в своей клинике. Сегодня вечером проверю. Теперь, если TFrame2 помещен в TFrame1 в коде ... Пожалуйста, пока не голосуйте против. <г> - person Rudy Velthuis; 18.07.2011