Доступ к StringGrid из другой формы
Отредактируйте тело для более подробной информации.
У меня есть форма под названием ENP, определенная в модуле EnpView. Форма ENP создается и отображается из события обработчика щелчка по элементу панели инструментов в главной форме (TPrincipal).
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
TENP.Create(self).Show();
end;
Форма enp знает (в публичном объявлении) сообщение clearGrid().
Форма ENP имеет TStringGrid с именем StringGrid. И кнопка называется "Добавить". При нажатии кнопки "Добавить" создается и отображается другая форма: Форма AddEnp, определенная в модуле EnpViewAdd.
procedure TENP.opAgregarClick(Sender: TObject);
begin
TAddEnp.Create(self).Show();
end;
Форма AddEnp, есть любые TEdits. Значения входных данных должны быть добавлены в EnpView.StringGrid.
Я пытаюсь это:
implementation
uses
EnpView, Main;
procedure TAddEnp.AgregarClick(Sender: TObject);
begin
{ Agrego el nodo xml }
Globals.Xml.agregarMuestra(muestra.Text);
Globals.Xml.insertEnp(muestra.Text,golpes.Text,metros.Text);
{ Send messages to EnpView Form }
ENP.clearGrid();
ENP.populateGrid();
end;
Сообщения ClearGrid завершаются сбоем в строке 1 с нарушением прав доступа:
procedure TENP.clearGrid();
begin
Self.StringGrid.RowCount := 2;
Self.StringGrid.Rows[1].Clear();
end;
Методы clearGrid работают, если они отправлены внутри класса. Есть идеи?.
2 ответа
Создайте свойство с именем, например, ENPForm в TAddENP и назначьте форму ENP сразу после ее создания. Объявите это следующим образом:
TAddENP = class(TForm)
private
FENPForm: TENP;
// all of your already existing declarations
public
property ENPForm: TENP read FENPForm write FENPForm;
end;
Теперь, когда у вас есть возможная ссылка на форму ENP, вы можете использовать ее по своему усмотрению.
При создании формы TAddENP сделайте следующее:
procedure TENP.opAgregarClick(Sender: TObject);
var
addForm: TAddENP;
begin
addForm := TAddEnp.Create(Self);
addForm.EnpForm := Self;
addForm.Show;
end;
Теперь вы создали вторую форму и дали ей безопасную ссылку на первую. Теперь они могут безопасно общаться друг с другом.
Я советую вам избегать того, чтобы одна форма работала с компонентами другого, потому что это увеличивает зависимость между ними. Вместо этого объявите для этого открытые методы, чтобы формы зависели от их интерфейсов, а не от их реализаций.
Надеюсь, это поможет.
Из вашего вопроса (я добавил code-style
чтобы было понятнее)
У меня есть форма называется
ENP
, определенный вEnpView
Блок.ENP
форма, создается и отображается из события обработчика щелчка элемента панели инструментов в главной форме (TPrincipal
).
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
TENP.Create(self).Show();
end;
Это ничего не делает с вашим ENP
переменная формы.
Вы создаете экземпляр TENP
сформировать класс и показать его, используя Show
, но ENP
переменная не назначена.
Вы не можете назначить экземпляр ENP
переменная, так как каждое нажатие кнопки создает новый экземпляр (так что у вас есть несколько экземпляров TENP
) вокруг.
Затем вы создаете запутанную зависимость TAddEnp
экземпляр и (никогда ENP
переменная).
Вы делаете это, создавая TAddEnp
экземпляр (почему TAddEnp
здесь, а не TAddENP
?) показать это используя Show
(давая пользователям возможность вернуться к TENP
экземпляр и снова нажмите на opAgregar
кнопка, чтобы создать больше экземпляров TAddEnp
):
procedure TENP.opAgregarClick(Sender: TObject);
begin
TAddEnp.Create(self).Show();
end;
Затем следует TAddEnp
зависит от ENP
переменная:
procedure TAddEnp.AgregarClick(Sender: TObject);
begin
//...
ENP.clearGrid();
ENP.populateGrid();
end;
Это действительно потерпит неудачу:
Сообщения ClearGrid завершаются сбоем в строке 1 с нарушением прав доступа:
procedure TENP.clearGrid();
begin
Self.StringGrid.RowCount := 2;
Self.StringGrid.Rows[1].Clear();
end;
Причина в том, что ENP
не назначен (по умолчанию это будет nil
) так внутри clearGrid
, Self
также будет nil
,
Решения, которые вы могли бы реализовать
- Держите один экземпляр
TENP
а такжеTAddEnp
вокруг, используяShowModal
заставить модальность запретить пользователю нажимать на одни и те же кнопки несколько раз. - Оставьте свой существующий
Show
поведение, но обязательный каждыйTAddEnp
экземпляр кTENP
Экземпляр, из которого он был создан.
Для первого решения ваш код станет таким:
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
ENP := TENP.Create(Application);
ENP.ShowModal();
ENP.Release();
ENP := nil;
end;
а также
procedure TENP.opAgregarClick(Sender: TObject);
begin
AddEnp := TAddEnp.Create(Application);
AddEnp.ShowModal();
AddEnp.Release();
AddEnp := nil;
end;
Второе потребует больше усилий, так как вам необходимо предотвратить использование существующих переменных.
- Удалить
ENP
переменная. - Удалить
AddENP
переменная.
Исправить self
-> Self
в методах
procedure TPrincipal.ENP1Click(Sender: TObject);
begin
TENP.Create(Self).Show();
end;
а также
procedure TENP.opAgregarClick(Sender: TObject);
begin
TAddEnp.Create(Self).Show();
end;
Здесь добавьте зависимость:
procedure TAddEnp.AgregarClick(Sender: TObject);
var
ENP: TENP;
begin
//...
ENP := Owner as TENP; // Owner will be of type TENP because of the Create(Self) in the ENP1Click method
ENP.clearGrid();
ENP.populateGrid();
end;