Некоторый способ изменить расположение компонентов, размеры, владение (свойства в целом) во время выполнения, следуя правилу времени разработки

У нас есть приложение, которое имеет много компонентов в формах (панели, вкладки, правки, списки и т. Д.). Но в зависимости от профиля пользователя, большинство из них могут быть заполнены автоматически и / или невидимы. Таким образом, пользователи могут выполнять свою работу быстрее.

Вопрос: есть ли более простой способ создания, размещения, смены владельца и т. Д. Во время выполнения? Я хотел бы создать 2 файла.dfm для данного модуля, а затем что-то сообщить приложению, какой файл.dfm использовать. Как: "Эй! Пользователь продвинутый, используйте Unit1Advanced.dfm!" Рабочий пример был бы хорош. Я хотел бы использовать это и в Delphi 7, но он должен работать по крайней мере в Delphi XE.

Что я знаю, что существует до сих пор:

  1. ComponentsToCode Функция из GExperts может создавать код из данного компонента, как указано в этом ответе Габром.
  2. Я мог бы создать 2 формы и создать желаемую во время выполнения. Но это означает один дополнительный файл.pas к каждому дополнительному файлу.dfm. Это будет сложнее поддерживать.
  3. Этот ответ, кажется, дает подсказку. Но я не привык к классам TReader и TWriter...

4 ответа

Решение

Предупреждение: этот ответ для полноты изложения вопроса и только для экспериментальных целей. Он никогда не должен использоваться в реальных сценариях.

Вам нужны два отдельных файла определения формы только для одного файла исходного кода.

Ключ должен использовать CreateNew конструктор. Чтобы процитировать документацию по нему:

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

  1. Сначала напишите свою расширенную форму:

    unit Advanced;
    
    interface
    
    uses
      Classes, Controls, Forms, StdCtrls;
    
    type
      TAdvancedForm = class(TForm)
        StandardGroupBox: TGroupBox;
          StandardButton: TButton;
        AdvancedGroupBox: TGroupBox;
          AdvancedButton: TButton;
        procedure StandardButtonClick(Sender: TObject);
        procedure AdvancedButtonClick(Sender: TObject);
      end;
    
    implementation
    
    {$R *.dfm}
    
    procedure TAdvancedForm.StandardButtonClick(Sender: TObject);
    begin
      Caption := Caption + ' Button1Click';
    end;
    
    procedure TAdvancedForm.AdvancedButtonClick(Sender: TObject);
    begin
      Caption := Caption + ' Button2Click';
    end;
    
    end.
    
  2. Создайте свое приложение и скопируйте Advanced.dfm в Standard.dfm,

  3. открыто Standard.dfm в текстовом редакторе удалите расширенные компоненты (в данном случае расширенный групповой блок, содержащий кнопку) и переименуйте форму и тип формы в (T)StandardForm:

    object StandardForm: TStandardForm
      ...
      object StandardGroupBox: TGroupBox
        ...
        object StandardButton: TButton
          ...
        end
      end
    end
    
  4. Добавьте ресурс для стандартной формы в Advanced.pas:

    {$R *.dfm}
    {$R Standard.dfm}
    
  5. И теперь с помощью следующего кода вы можете открыть оба определения формы для одного и того же исходного файла:

    uses
      Advanced;
    
    procedure TForm1.OpenAdvancedFormClick(Sender: TObject);
    var
      Form: TAdvancedForm;
    begin
      Form := TAdvancedForm.Create(Application);
      Form.Show;
    end;
    
    procedure TForm1.OpenStandardFormClick(Sender: TObject);
    var
    {
      Form: TAdvancedForm; // This is tricky! The form we are about to create has
                           // no AdvancedGroupBox nor AdvancedButton, so make sure
                           // you are not calling it with code completion.
      Form: TStandardForm; // Compiler has no knowledge of TStandardForm!
    }
      Form: TForm;         // So declare your form as TForm!
    begin
      // But create it as TAdvancedForm, otherwise components will not be found!
      Form := TAdvancedForm.CreateNew(Application);
      ReadComponentRes('TStandardForm', Form);
      Form.Show;
    end;
    

Я могу дать вам решение, основанное на вашем пункте 2. Начните с формы для неопытного пользователя, разместите все необходимые элементы управления и внедрите необходимый код в файл pas. Затем создайте новую форму, унаследованную от первой, и приспособьте ее к потребностям опытного пользователя. При необходимости вы также можете добавить некоторые реализации.

Более гибкий подход может заключаться в наследовании обеих форм от общего предка. Реальная реализация этой схемы сильно зависит от вашей ситуации.

Ваше желание иметь только один файл.pas для нескольких файлов.dfm: почти невозможно, но и немного непонятно: код будет ограничен менее продвинутой формой возможно, но на самом деле не рекомендую.

Относительно ваших требований разделения:

  • Создание: Создайте два дизайна и сделайте это с помощью Visual Form Inheritance (VFI), как упоминает Уве, чтобы у вас не было проблемы с отдельным обслуживанием.
  • Положение и размеры: это очень плохая идея. Позвольте элементам управления оставаться в одном и том же месте для каждого пользователя. Пользователи могут получить расширенные привилегии и быть шокированы незнакомой договоренностью. Единственное исключение, которое я бы сделал, - это минимальный размер формы: расширенная версия может быть выше и / или шире.
  • Смена владельца: Да, я понимаю, что вы имеете в виду, но элементы управления не принадлежат пользователю и не должны. Реализуйте некоторый контроллер, который имеет дело с тем, какой тип формы должен быть создан.

Если VFI не подходит, я предлагаю вам создать только расширенную форму и контролировать скрытие расширенных элементов управления, установив Visible свойство связанных действий. Сделайте это в или через сеттер для Advanced: Boolean свойство, которое должно существовать. Или сгруппируйте все расширенные элементы управления в один или несколько контейнеров: групповые блоки, панели или фреймы, такие как комментарии LU RD. Затем просто установите видимость этого контейнера. Существующие полосы прокрутки будут соответственно корректироваться или исчезать. Обратите внимание, что вы все еще можете обратиться к этим элементам управления, даже если вы не хотите.

Компоненты DevExpress ExpressLayout могут быть полезны - см. http://devexpress.com/Products/VCL/ExLayoutControl/

Они обеспечивают настройку формы во время выполнения - настройку управления во время выполнения - независимость от разрешения экрана и многое другое

Другие вопросы по тегам