2013-07-14 7 views
0

Редактировать тело для получения более подробной информации.Доступ к 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 работает, если отправить в классе. Есть идеи ?.

+0

ENP назначается? – bummi

+0

ENP - это форма внутри первого блока. ENP, уже созданная при выполнении второй формы. – ramiromd

+0

Что такое объявление 'stringgrid'? это назначено? поместите точку останова на проблемную строку и перед ее выполнением оцените «указатель (Self)» и «pointer (Self.stringgird)», имеют ли они какое-либо разумное значение –

ответ

1

Создать свойство с именем, например, ENPForm в TAddENP и назначьте E NP формируется сразу после его создания. Объявить его следующим образом:

TAddENP = class(TForm) 
private 
    FENPForm: TENP; 

// all of your already existing declarations 

public 
    property ENPForm: TENP read FENPForm write FENPForm; 
end; 

Теперь, когда у вас есть возможность ссылки на ЕПС форму, вы можете использовать его, как вам нравится.

При создании TAddENP формы, выполните следующие действия:

procedure TENP.opAgregarClick(Sender: TObject); 
var 
    addForm: TAddENP; 
begin 
    addForm := TAddEnp.Create(Self); 
    addForm.EnpForm := Self; 
    addForm.Show; 
end; 

Теперь вы создали вторую форму и дал ему безопасную ссылку на первый. Теперь они могут спокойно разговаривать друг с другом.

Советуем избегать использования одной формы других компонентов, потому что это вызывает зависимость между ними. Вместо этого объявляйте общедоступные методы для этого, поэтому формы будут зависеть от их интерфейсов, а не от их реализаций.

Надеюсь, это поможет.

+0

ваш ответ работает нормально !! Благодаря ! – ramiromd

0

Из Вашего вопроса (я добавил 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.

решения можно реализовать

  1. Держите один экземпляр TENP и TAddEnp вокруг, используя ShowModal, чтобы заставить модальность запретить пользователю нажимать на те же кнопки несколько раз.
  2. Сохраняйте существующее поведение 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;