控制uniFrame显示的一个管理类

利用uniGUI Frame的机制来搭建项目,是非常好的实现方式,uniGUI的主要Demo就是用这种方式来实现的。

对此,我实现了一个类,来管理Frame的显示。


unit FrameMgn;


interface


uses

  System.Classes, System.Contnrs, System.SysUtils, Vcl.Controls, uniGUIFrame, uniGUIClasses;


type


  TFrameManager = class(TComponent)

  private

    FFrameList: TObjectList;

    FActiveFrame: TUniFrame;

    FContainerPanel: TUniCustomContainerPanel;

    procedure SetActiveFrame(const Value: TUniFrame);

    procedure SetContainerPanel(const Value: TUniCustomContainerPanel);

    function GetEditFrameClassName(aClassName: String): string; // 根据给定的参数,返回对应的编辑Frame的类名.

    function GetFrameInstance(aFrameClassName: string): TUniFrame;

  public

    constructor Create(AOwner: TComponent); override;

    destructor Destroy; override;

    procedure ShowFrame(aClassName: String);

    procedure HideFrame;


    property ActiveFrame: TUniFrame read FActiveFrame write SetActiveFrame;

    property ContainerPanel: TUniCustomContainerPanel read FContainerPanel write SetContainerPanel;

  end;


implementation


{ TFrameManager }


uses MainModule;


constructor TFrameManager.Create(AOwner: TComponent);

begin

  inherited;

  FFrameList := TObjectList.Create;

  FFrameList.OwnsObjects := False;

end;


destructor TFrameManager.Destroy;

begin

  FFrameList.Free;

  inherited;

end;


function TFrameManager.GetEditFrameClassName(aClassName: String): string;

var

  cn: String;

begin


  Result := aClassName;

  if UniMainModule.UserLoginCode <> '' then // 如果登录状态

  begin

    cn := aClassName + 'Edit';


    if (GetClass(cn) <> nil) and (UniMainModule.FuncList.Locate('FAndroid_ClassName', cn, [])) then

      Result := cn;

  end;


end;


function TFrameManager.GetFrameInstance(aFrameClassName: string): TUniFrame;

var

  fr: TUniFrame;

  frc: TuniFrameClass;

  I: Integer;

begin


  for I := 0 to FFrameList.Count - 1 do

  begin

    if CompareText(FFrameList.Items[I].ClassName, aFrameClassName) = 0 then

    begin

      Result := TUniFrame(FFrameList.Items[I]);

      exit;

    end;

  end;


  frc := TuniFrameClass(GetClass(aFrameClassName)); // findClass找不到类会产生异常,所以换用GetClass。

  if frc <> nil then

  begin

    fr := frc.Create(Self.Owner); // frc的Owner必须是TuniForm或TUniFrame

    fr.Name := aFrameClassName.Substring(1);

    FFrameList.Add(fr);

    Result := fr;

  end

end;


procedure TFrameManager.HideFrame;

var

  I: Integer;

  obj: TUniFrame;

begin


  if Assigned(ActiveFrame) then

  begin

    ActiveFrame.Parent := nil; // 可以,但urlFrame不显示内容:利用UniURLFrame.URL属性取代HTML属性解决.

    for I := 0 to FFrameList.Count - 1 do

    begin

      // 如果一个Frame需要重建才能正常显示,则利用Frame.Tag=1来标记要重建.

      obj := FFrameList.Items[I] as TUniFrame;

      if obj.Tag = 1 then

      // if FFrameList.Items[I].ClassName = 'TYangZhiFuWuFrameEdit' then

      begin

        FreeAndNil(obj);

        FFrameList.Delete(I);

        exit;

      end;

    end;

  end;


end;


procedure TFrameManager.SetActiveFrame(const Value: TUniFrame);

begin

  FActiveFrame := Value;

end;


procedure TFrameManager.SetContainerPanel(const Value: TUniCustomContainerPanel);

begin

  FContainerPanel := Value;

end;


procedure TFrameManager.ShowFrame(aClassName: String);

var

  fr: TUniFrame;

  frc: TuniFrameClass;

  cn: string;

begin


  // 如果当前显示的Frame正是选择要显示的直接退出.

  if Assigned(ActiveFrame) then

    if CompareText(aClassName, ActiveFrame.ClassName) = 0 then

      exit;


  HideFrame;


  cn := GetEditFrameClassName(aClassName);


  fr := GetFrameInstance(cn);

  if fr <> nil then

  begin

    fr.Align := alClient;

    fr.Parent := FContainerPanel;

    ActiveFrame := fr;

  end;


end;


end.


有了这个类,再显示一个Frame就方便多了。