Pascal предава изглед на списък от основна форма към немодална форма

Имам изглед на списък в основната си форма, към която искам друга немодална форма, за да мога да добавя неща. Как да предам списъка към немодалната форма? Формата, която искам да мога да променя, се показва от MainForm при натискане на бутон, само с Form.Show.

Трябва също така да поясня, че искам формулярът да не използва основната форма, за да избегна кръгова препратка.


person wentimo    schedule 10.04.2012    source източник
comment
** Трябва също така да поясня, че искам формулярът да не използва основната форма, за да избегна кръгова препратка.   -  person wentimo    schedule 10.04.2012


Отговори (3)


Най-простият и най-добрият начин би бил да добавите метод към получаващия формуляр – тоест формулярът с ListView върху него – който казва „AddThingsToListView“ и да приеме нещата, които искате да добавите (Вероятно TListItem?)

По този начин можете да се обадите

MyMainForm.AddThingsToListView(ANewListItem);

отвсякъде.

С други думи, не предавайте изгледа на списък към немодалната форма; вместо това, накарайте основния формуляр да може да приема допълнения към неговия списък.

person Nick Hodges    schedule 10.04.2012
comment
Това не работи. Не можете да преминете ANewListItem, тъй като трябва да имате самия изглед на списък, за да създадете нов елемент. По-конкретно, трябва да се обадите на TListItems.Add или на някой от неговите приятели. - person David Heffernan; 10.04.2012

Забележка: Въпросът първоначално беше маркиран с Delphi. Не познавам FPC/Lazarus, така че някои от подробностите може да не са точни по-долу, но концепциите все още са валидни.


Предполагам, че имате глобална променлива, представляваща основната форма, наречена MainForm в името на аргумента. Най-бързият и прост подход е просто да използвате MainForm.ListView, за да позволите на другия ви формуляр да препраща към списъчния изглед на основния формуляр.

Не съм много запален по този подход, тъй като това означава, че другата форма зависи от изпълнението на основната форма.


Като алтернатива можете да прехвърлите препратка към изгледа на списък към другия формуляр. Например можете да добавите SetListView процедура към другата си форма:

type
  TMyOtherForm = class(TForm)
  private
    FListView: TListView;
  public
    procedure SetListView(Value: TListView);
  end;
.....
procedure TMyOtherForm.SetListView(Value: TListView);
begin
  FListView := Value;
end;

След това в главната форма, вероятно в манипулатора на събития OnCreate за главната форма, можете да извикате този метод:

procedure TMainForm.FormCreate(Sender: TObject);
begin
  MyOtherForm.SetListView(ListView);
end;

Това всъщност не е много по-добро от първото предложение. Другата форма все още зависи от изпълнението на основната форма, макар и може би по-малко значима зависимост.


Ако искате да запазите двата формуляра дори по-малко свързани, тогава основният формуляр може да изложи метод, който приема допълнения към списъка:

procedure TMainForm.AddToList(const Name: sting; const Time: TDateTime);
var
  Item: TListItem;
begin
  Item := ListView.Items.Add;
  Item.Caption := Name;
  Item.SubItems.Add(DateTimeToStr(Time));
end;

В другата си единица за формуляри добавяте основната единица за формуляр към клаузата за използване в раздела за изпълнение. Това ви позволява достъп до глобалната променлива MainForm и можете да извикате

MainForm.AddToList(Name, Time);

Този подход е най-добрият според мен, защото позволява на основната форма да запази внедряването на списъка лично за себе си.


Заявявате в коментар, че искате да избегнете всякакви кръгови препратки поради клаузи uses. Това е лесно за уреждане, тъй като нито едно от горните не изисква модификации на клаузата uses от раздела за интерфейс от двете въпросни единици.

person David Heffernan    schedule 10.04.2012
comment
Вашият трети подход изглежда като това, което бих искал да направя. Къде точно ще декларирате тази процедура? Това са публичните декларации на mainform? а в другата форма бихте ли направили просто TMainForm.AddToList(), без да се налага да използва TMainform? - person wentimo; 10.04.2012
comment
Да, трябва да е публичен в TMainForm. Добавяте основната си единица за формуляр към клаузата за използване на секцията за внедряване в другата си единица. След това правите MainForm.AddToList. Не опитвайте TMainForm.AddToList. Това няма да работи. - person David Heffernan; 10.04.2012
comment
Очевидно всъщност нямам глобална променлива за mainform. Къде бих декларирал основната си форма като глобална? - person wentimo; 10.04.2012
comment
@wentime Това е необичайно. Нормално приложение на Delphi добавя това за вас по подразбиране. .dpr обикновено създава основния формуляр и го присвоява на глобална променлива, която е декларирана в раздела за интерфейс на модула на вашия основен формуляр. Трябва да се обадите на Application.CreateForm, за да направите това някъде? Къде правите това и какво правите с препратката, която предавате на Application.CreateForm? - person David Heffernan; 10.04.2012
comment
Използвам Lazarus и не виждам извикване на CreateForm никъде в кода за unit1. Направих ли грешка при създаването на тази единица? - person wentimo; 11.04.2012
comment
Според въпроса използвате Delphi!! Както и да е, не знам много за Lazarus и FPC. Обаждането до Application.CreateForm обикновено ще живее в .dpr файла. - person David Heffernan; 11.04.2012
comment
Това би обяснило голяма част от объркването ми, исках да сложа паскал там! - person wentimo; 11.04.2012
comment
Концепциите, обхванати в моя отговор, все още се прилагат за FPC/Lazarus, въпреки че предполагам, че внедряването на списъчен изглед може да се различава донякъде. - person David Heffernan; 11.04.2012
comment
Application.CreateForm е във файла *.lpr на проекта и има същото значение като в Delphi. - person TLama; 11.04.2012
comment
Добре, така че опитах първия ви метод и получих следната грешка: unit1.pas(50,32) Само методите на класа, свойствата на класа и променливите на класа могат да бъдат достъпни в методите на класа. Това се случва в MyOtherForm.SetListView(ListView); обадете се - person wentimo; 11.04.2012
comment
Съобщението за грешка ви казва отговора. Вие извиквате това от метод на клас. Трябва да извикате от метод на екземпляр. - person David Heffernan; 11.04.2012

Какво правя: за този вид ситуация: обикновено декларирам модул за данни и поставям по-голямата част от кода, който не се вписва добре в библиотечни единици без GUI, в модула за данни. Модулът за данни може да препраща към формулярите и обратно, но нито една от формите не препраща една към друга.

В този пример вашият Form2 може да използва DataModule и можете да направите едно от следните:

  1. Имайте глобална препратка към ListView на MainForm в модула с данни и използвайте това от вашия формуляр.
  2. Имайте функция/клас в модула с данни, който ви позволява да актуализирате списъка и да го извикате от формуляра си.

Така или иначе, вашата форма трябва да знае само за модула за данни, а модулът за данни прави останалото. Можете да добавяте/изтривате/променяте формуляри и обикновено трябва само да актуализирате DM.

person Noah    schedule 13.08.2012