как сохранить связи между элементами управления при копировании? - PullRequest
2 голосов
/ 27 мая 2020

Я хочу спросить, как сохранить элементы управления, когда я делаю копию элемента управления. например, у меня есть поле редактирования, которым можно управлять с помощью ползунка для изменения значения. когда я делаю копию с помощью этого кода, я получаю копию элементов, но ползунок перестает контролировать значения поля редактирования. как я могу это исправить?

 TypInfo;

procedure CloneProperties(const Source: TControl; const Dest: TControl);
var
 ms: TMemoryStream;
 OldName: string;
begin
 OldName := Source.Name;
 Source.Name := ''; // needed to avoid Name collision
 try
   ms := TMemoryStream.Create;
   try
     ms.WriteComponent(Source);
     ms.Position := 0;
     ms.ReadComponent(Dest);
   finally
     ms.Free;
   end;
 finally
   Source.Name := OldName;
 end;
end;

procedure CloneEvents(Source, Dest: TControl);
var
 I: Integer;
 PropList: TPropList;
begin
 for I := 0 to GetPropList(Source.ClassInfo, [tkMethod], @PropList) - 1 do
   SetMethodProp(Dest, PropList[I], GetMethodProp(Source, PropList[I]));
end;

procedure DuplicateChildren(const ParentSource: TWinControl;
 const WithEvents: Boolean = True);
var
 I: Integer;
 CurrentControl, ClonedControl: TControl;
begin
 for I := ParentSource.ControlCount - 1 downto 0 do
 begin
   CurrentControl := ParentSource.Controls[I];
   ClonedControl := TControlClass(CurrentControl.ClassType).Create(CurrentControl.Owner);
   ClonedControl.Parent := ParentSource;
   CloneProperties(CurrentControl, ClonedControl);
   ClonedControl.Name := CurrentControl.Name + '_';
   if WithEvents then
     CloneEvents(CurrentControl, ClonedControl);
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 DuplicateChildren(Panel1);
end;

1 Ответ

5 голосов
/ 27 мая 2020

Если я вас не неправильно понял, ваши CloneProperties, похоже, не имеют ничего общего с вопросом, который вы задаете. В вашем примере элемента управления редактирования E1 и ползунка S1 вы можете клонировать их оба для создания E2 и S2, но где-то в вашем коде должен быть оператор, который изменяет значение в E1 в зависимости от значения S1. Однако, как вы, скорее всего, написали, этот оператор не применяется к E2 и S2.

Самый простой способ обойти это - написать метод, который принимает экземпляры компонентов и связывает операции двое вместе. например,

  procedure TForm1.SetEditControlFromSlider(AnEdit : TEdit; ASlider : { TWhatever the slider actually is);
  begin
    // Set AnEdit's value from ASlider's properties
  end;

Затем вы можете вызвать это с помощью пар Edit / Slider, например:

  SetEditControlFromSlider(E1, S1);
  [...]
  SetEditControlFromSlider(E2, S2);

Я могу представить, что вам может не понравиться это делать.

ИМО, самое чистое решение - не пытаться полностью клонировать компоненты и создать TFrame, содержащий Edit, Slider и код, который их соединяет, а затем добавить в вашу форму столько экземпляров кадра, сколько вам нужно . Это так же просто, как падение с бревна.

type
  TEditFrame = class(TFrame)  // needs to be in its own unit, Used by your form
    Edit1: TEdit;
    TrackBar1: TTrackBar;
    procedure TrackBar1Change(Sender: TObject);
  private
  public
  end;
  [...]
  procedure TEditFrame.TrackBar1Change(Sender: TObject);
  begin
    Edit1.Text := IntToStr(TrackBar1.Position)
  end;

Затем вы можете добавить клоны кадра в TForm1 с помощью

  procedure TForm1.Button1Click(Sender: TObject);
  var
    AFrame : TEditFrame;
  begin
    Inc(FrameCount); // Field of TForm1
    AFrame := TEditFrame.Create(Self);
    AFrame.Name := AFrame.Name + IntToStr(FrameCount);
    AFrame.Parent := Self;
    AFrame.Top := AFrame.Height * FrameCount;
  end;

Обратите внимание, что, поскольку код, связывающий два компонента, TrackBar1Change, он компилируется в единицу фрейма, он автоматически используется каждым экземпляром фрейма, который вы создаете, без необходимости «клонировать» код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...