Некоторый способ изменить расположение компонентов, размеры, собственность (свойства в целом) во время выполнения, следуя правилу времени разработки - PullRequest
1 голос
/ 10 декабря 2011

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

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

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

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

Ответы [ 4 ]

4 голосов
/ 10 декабря 2011

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

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

3 голосов
/ 10 декабря 2011

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

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

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

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

2 голосов
/ 13 декабря 2011

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

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

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

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

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.

Создайте свое приложение и скопируйте Advanced.dfm в Standard.dfm.

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

object StandardForm: TStandardForm
  ...
  object StandardGroupBox: TGroupBox
    ...
    object StandardButton: TButton
      ...
    end
  end
end

Добавьте ресурс для стандартной формы в Advanced.pas:

{$R *.dfm}
{$R Standard.dfm}

И теперь с помощью следующего кода вы можете открыть оба определения формы для одного и того же исходного файла:

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;
0 голосов
/ 10 декабря 2011

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

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

...