加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 在运行时删除和替换可视组件

发布时间:2020-12-15 10:13:11 所属栏目:大数据 来源:网络整理
导读:例如,是否可以在运行时使用实例化(有条件地)的子类组件替换和释放TEdit?如果是这样,应该如何以及何时完成?我试图将父设置为nil并在表单构造函数和AfterConstruction方法中调用free(),但在这两种情况下我都遇到了运行时错误. 更具体地说,我遇到了访问冲突错
例如,是否可以在运行时使用实例化(有条件地)的子类组件替换和释放TEdit?如果是这样,应该如何以及何时完成?我试图将父设置为nil并在表单构造函数和AfterConstruction方法中调用free(),但在这两种情况下我都遇到了运行时错误.

更具体地说,我遇到了访问冲突错误(EAccessViolation).看起来弗朗索瓦是正确的,因为他说在框架构造中释放组件会使用Form来控制内务管理.

解决方法

这个更通用的例程可以使用Form或Frame(更新为使用新控件的子类):
function ReplaceControlEx(AControl: TControl; const AControlClass: TControlClass; const ANewName: string; const IsFreed : Boolean = True): TControl;
begin
  if AControl = nil then
  begin
    Result := nil;
    Exit;
  end;
  Result := AControlClass.Create(AControl.Owner);
  CloneProperties(AControl,Result);// copy all properties to new control
  // Result.Left := AControl.Left;   // or copy some properties manually...
  // Result.Top := AControl.Top;
  Result.Name := ANewName;
  Result.Parent := AControl.Parent; // needed for the InsertControl & RemoveControl magic
  if IsFreed then
    FreeAndNil(AControl);
end;

function ReplaceControl(AControl: TControl; const ANewName: string; const IsFreed : Boolean = True): TControl;
begin
  if AControl = nil then
    Result := nil
  else
    Result := ReplaceControlEx(AControl,TControlClass(AControl.ClassType),ANewName,IsFreed);
end;

使用此例程将属性传递给新控件

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 TFrame1.AfterConstruction;
var
  I: Integer;
  NewEdit: TMyEdit;
begin
  inherited;
  NewEdit := ReplaceControlEx(Edit1,TMyEdit,'Edit2') as TMyEdit;
  if Assigned(NewEdit) then
  begin
    NewEdit.Text := 'My Brand New Edit';
    NewEdit.Author := 'Myself';
  end;
  for I:=0 to ControlCount-1 do
  begin
    ShowMessage(Controls[I].Name);
  end;
end;

注意:如果您在框架的AfterConstruction中执行此操作,请注意托管表单构造尚未完成.释放控件可能会导致很多问题,因为你搞乱了Form控件的内务管理.如果您尝试阅读ShowMessage中显示的新编辑标题,请查看您获得的内容…在那种情况下,你会想要使用… ReplaceControl(Edit1,’Edit2′,False)然后做一个… FreeAndNil(EDIT1)后来.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读