Конференция "Основная" » Реализация интерфейса-мастера.
 
  • Kolan © (06.03.08 09:42) [60]
    > Сам же написал: «такой трудно сопроваждать». И это понятно,
    > т.к. вся логика разбросана по разным местам.

    А, я думал он наоборот считает что это нормально…

    Я честно так и не понял что конкретно вы предлагаете.

    Давайте на простом примере.

    Есть 3 формы.

    TForm1, TForm2, TForm3



    Вы говорите используй состояния — ок. Есть 3 состояния:

    TStates =
    (
     sState1,
     sState2,
     sState3
    );



    Как предлагается все это увязать? Пусть из формы 1 надо вытащить и сохранить переменную S и передать её TForm3.

    Варик с сразу созданными формами еще плох тем, что придется делать очищение их.


    > Keep It Simple Stupid

    Вот клянусь именно этого и хочу, но не получается :(
  • oxffff © (06.03.08 10:36) [61]
    NO COMMENTS. :)
  • Семеныч (06.03.08 10:49) [62]
    > Kolan ©   (06.03.08 09:42) [60]

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

    Не мудри. Из пушки по воробьям стреляешь. Это не та задача, где требуется Гради Буча сначала проштудировать.
  • clickmaker © (06.03.08 11:06) [63]

    > Пусть из формы 1 надо вытащить и сохранить переменную S
    > и передать её TForm3.

    а какие проблемы?
    массив параметров, индекс = шаг
    для пущей универсальности в структуре, которая хранит параметры отдельно взятого шага, можно юзать Variant или что-то типа Name = Value
  • clickmaker © (06.03.08 11:22) [64]

    > [63] clickmaker ©   (06.03.08 11:06)
    >
    > > Пусть из формы 1 надо вытащить и сохранить переменную
    > S
    > > и передать её TForm3.

    кстати, о птичках.
    Почему бы не сделать список данных форм, ключом в котором будет класс формы (или имя класса)?
    Форма при по нажатию на Next просто добавляет/обновляет данные в этот список.
    Тогда на любом шаге можно обратится к данным одной из предыдущих форм вызовом Data := GetFormData(Form1).
    Где data - наследник абстрактного класса наподобие TFormData. Из экземпляров наследников этого класса и состоит список.
    форма 3 знает, что ей надо получить именно TForm1Data:
    var
     Data: TForm1data;

    Data := GetFormData('Form1');
  • KSergey © (06.03.08 13:23) [65]
    > Семеныч   (06.03.08 10:49) [62]
    > Ветка держится неделю. Ей-богу, за это время можно было
    > уже весь визард написать.

    Вот все о том же пытаются сказать.
    Блин, давно бы уже написал хоть как-нибудь - и было бы видно: хорошо это или нет.
    Бесполезно так вот на расстоянии получить ответ, который стопудово будет самым правильным.
    Хотя я помнимаю это желание, сам им часто страдаю.
  • KSergey © (06.03.08 13:30) [66]
    По поводу передаваемых данных "из формы в форму" - предлагаю уйти от этой практики (уже писал об этом!)
    Раз уж это цельный визард - то наверняка суть не столько в том, чтобы из формы в форму что-то передать - а настроить несколькими формами параметры некоего цельного внешнего объекта.
    А значит и разносить данные по фотмама - нецелесообразно, по-моему. Даже если часть данных, нужных для форм, не требуются внешнему объекту - ну просто сгруппировать соотв. образом это все в структуре - да и всех дел.
  • KSergey © (06.03.08 13:52) [67]
    > Kolan ©   (06.03.08 09:42) [60]
    > Есть 3 формы.
    >
    > TForm1, TForm2, TForm3
    >
    > Есть 3 состояния:
    >
    > TStates = ( sState1,  sState2,  sState3 );
    > Пусть из формы 1 надо вытащить и сохранить переменную S и передать её TForm3.

    Я не понимаю что тут может быть непонятно. Лучже бы ваш пример глянуть.
    Вот мое видение, очень схематично. Предполагаю (для краткости), что все формы созданы ранее. Конструкции пишу очень на память, в хелп за синтаксисом лазить лень. Так что формально может и не компилируемый код.
    mrNext, mrBack, mrCancel - просто доопретелил бы свои, отсутствующие.

    Расширим TStates:

    TStates = ( sState1,  sState2,  sState3 , sStateCanceled, sStateEnded );

    Ну и код некоей процедуры, запускаемой при старте программы:

    CurState: TStates;

    CurState := sState1;

    while ((CurState <> sStateCanceled) OR (CurState <> sStateEnded))
    begin
      case CurState
        sState1:
           begin
              Res := Form1.ShowModal;
              if Res <> mrCanceled then
                DataModule.ParameterS = Form1.S;
              if Res = mrNext then CurState := State2;
           end;
        sState2:
           begin
              Res := Form2.ShowModal;
              if Res = mrNext then CurState := State3
              else if Res = mrBack then CurState := State1;
           end;
        sState3:
           begin
              Form3.S := DataModule.ParameterS;
              Res := Form3.ShowModal;
              if Res = mrBack then CurState := State2;
           end;
    end;

    // Здесь в CurState имеем sStateCanceled или sStateEnded
    // Делаем что нам надо после завершения визарда, если его завершение вообще предполагается.



    Этот вариант для случая, когда нужны непоследовательные варианты перехода между шагами, зависящие от введенных данных (здесь просто не показано для простоты). Добавляется в логику if Res = ... then CurState := ...

    Если же все перемещения только тупо вперед-назад - то проще массив ссылок на формы (или классы) - и тупо индекс гонять. Или если перечисление (классов, например) - то к переменной типа перечисление применимы Inc/Dec (если не ошибаюсь) и возможность определения граничный это элемент или нет.
  • KSergey © (06.03.08 13:54) [68]
    Да, не факт, что sStateCanceled, sStateEnded  есть смысл добавлять в общую кучу состояний
    Может удобнее отдельный флажек завести.
  • Kolan © (06.03.08 15:05) [69]
    > По поводу передаваемых данных «из формы в форму» —

    Из формы в ворму я ниче не буду передавать. Буду использовать посетителя, то есть форма для работы будет требовать интерфейсы. Это метод проверен, и он оч. удобен.


    > Блин, давно бы уже написал хоть как-нибудь

    Я пока другие места прорабатывал…


    > [67] KSergey ©   (06.03.08 13:52)

    Вот, пример которого я хотел :)


    if Res <> mrCanceled then
               DataModule.ParameterS = Form1.S;
             if Res = mrNext then CurState := State2;


    В вот этих результатов (mrCanceled, mrNext…) может быть еще несколько, на каждой форме разное кол-во. На одной «Добавить», на другой «Настройки» . Придется при возникновении нового дополнять перечисление.

    В итоге вроде у меня получается почти тоже самое, только строки типа '0.1' надо заменить на константы. А вот с возврящаемыми значениями у меня лучьше имхо, они прям из экшенов беруться…

    Вообще пример я понял. Благодарю, пригодится.
  • Kolan © (06.03.08 15:10) [70]
    Все, я все понял, сделаю как KSergey, только с возвращ. занчениями сделаю как у меня…
    Я понял в чем тут плюс, формами легко управлять. Благодарю еще раз :)
  • Kolan © (06.03.08 16:21) [71]
    sState2:
          begin
             Res := Form2.ShowModal;
             if Res = mrNext then CurState := State3
             else if Res = mrBack then CurState := State1;
          end;
       sState3:
          begin
             Form3.S := DataModule.ParameterS;
             Res := Form3.ShowModal;
             if Res = mrBack then CurState := State2;
          end;



    Интересно, а как при возврашении назад из шага 3 в шаг 2 показать форму? Она же уже показана, причем модально…
  • clickmaker © (06.03.08 16:23) [72]

    > как при возврашении назад из шага 3 в шаг 2 показать форму?
    > Она же уже показана, причем модально

    для каждой страницы - форма модально?
    почему не одна форма с меняющимися фреймами?
  • Kolan © (06.03.08 16:25) [73]
    > [72] clickmaker ©   (06.03.08 16:23)
    > почему не одна форма с меняющимися фреймами?

    Потому, что ты понимаешь как это сделать, а я нет. Приведи пример…
  • clickmaker © (06.03.08 16:33) [74]

    > Приведи пример…

    dfm сюда выложить? Злой ты ))
    понаделай фреймов, а потом по нажатию кнопок на форме убирай один, создавай и показывай другой
    Parent := Form, ну и тыпы

    впрочем, непонятно как [71] сочетается с [4] - "Визард (собссно есть свой) — это страницы (на подобии PageControl) которые лежат на форме"
  • Kolan © (06.03.08 16:42) [75]
    Вопрос снимается, она же по ShowModal закрывается…
  • Kolan © (06.03.08 16:47) [76]
    > понаделай фреймов, а потом по нажатию кнопок на форме убирай
    > один, создавай и показывай другой

    Понимаешь, когда ты так говориш, то я в принципе понимаю. Но в принципе я и так могу понять. А точо понять что ты предлагаешь можно только на мини примере. Типа [67] KSergey.


    > впрочем, непонятно

    Суть в предыдущих 70 постах. :)
  • clickmaker © (06.03.08 16:59) [77]

    > только на мини примере

    type
     TWizardFrame = class(TFrame)
     ...

     TStep1Frame = class(TWizardFrame)
     ...
     TStep25Frame = class(TWizardFrame)
     ...
     TWizardFrameClass = class of TWizardFrame;

    var
     FCurrentFrame: TFrame;

    procedure TWizardForm.Next()
    begin
      FcurrentFrame.SaveData();
      FCurrentFrame.Free;
      CurrFrameClass := GetNextFrameClass(Step); // TWizardFrameClass
      FCurrentFrame :=  CurrFrameClass.Create(Self);
      FCurrentFrame.Parent := Self;
      FCurrentFrame.Visible := true;
    end;

    как-то так
  • b z (06.03.08 17:07) [78]

    > Вопрос снимается, она же по ShowModal закрывается…

    формы, патерны, классы, "фигасы" ... :(


    > FCurrentFrame.Free;

    Можно (или нужно) "захэшировать", с учетом - Back (Previous) и т.д.
  • KSergey © (06.03.08 17:13) [79]
    > b z   (06.03.08 17:07) [78]
    > Можно (или нужно) "захэшировать", с учетом - Back (Previous)  и т.д.

    Автору хочется напрягать менеджер кучи и ядро винды для создания окон и выделения/уничтожения для них GDI-объектов по полной программе.
    Флаг ему в руки.
 
Конференция "Основная" » Реализация интерфейса-мастера.
Есть новые Нет новых   [134483   +44][b:0.001][p:0.002]