Domanda

Ho alcune forme nella mia richiesta, che hanno differenti "stati" a seconda di ciò che l'utente sta facendo; per exemple quando si elencano attraverso le sue file il modulo mostra alcuni dati circa il file in una griglia, ma se si fa clic su qualche pulsante della griglia è sostituito da un grafico relativo ad esso. È presto detto, i controlli nel modulo dipende dal ciò che l'utente vuole fare.

Naturalmente il modo più ovvio di farlo mostrava / controlli Hidding, se necessario, funziona come un fascino per i piccoli numeri, ma una volta raggiunto 10/15 + controlli per stato (o più di 3 stati in realtà) è inutilizzabile.

sto sperimentando TFrames in questo momento: creo una cornice per ogni stato, ho quindi creare un'istanza di ogni frame nella mia forma uno sopra l'altro e poi ho visualizzare solo quello che voglio con Visible - pur avendo alcuni controlli su di esso, fuori da ogni cornice dal momento che tutti loro di condividere.

E 'questo il modo giusto di fare quello che voglio, o mi sono perso qualcosa lungo la strada? Ho pensato che avrei potuto creare una sola istanza tframe e poi ha scelto quale visualizzare in essa, ma non sembra in questo modo.

Grazie

È stato utile?

Soluzione

Sembra cornici sono una scelta eccellente per questo scenario. Mi piacerebbe aggiungere che è possibile utilizzare un telaio di base e Visual Inheritance per creare un'interfaccia comune.

E alla seconda parte: la progettazione di un telaio come una forma, ma lo si utilizza come un controllo, ben poche restrizioni. Si noti che si potrebbe facilmente utilizzare Create / Free invece di Mostra / Nascondi. Che cosa è meglio dipende da come risorsa-pesanti sono.

Altri suggerimenti

C'è un modo migliore per gestire trattare con i fotogrammi che non ci vorrà fino quasi quanto la memoria. creando dinamicamente il frame può essere una soluzione molto elegante. Ecco come ho fatto in passato.

Nel modulo, aggiungere una proprietà e un setter che gestisce il posizionamento di esso sulla forma:

TMyForm = class(TForm)
private
  FCurrentFrame : TFrame;
  procedure SetCurrentFrame(Value : TFrame);
public
  property CurrentFrame : TFrame read FCurrentFrame write SetCurrentFrame;
end;

procedure TMyForm.SetCurrentFrame(Value : TFrame)
begin
  if Value <> FCurrentFrame then
  begin
    if assigned(FCurrentFrame) then
      FreeAndNil(FCurrentFrame);
    FCurrentFrame := Value;
    if assigned(FCurrentFrame) then
    begin
      FCurrentFrame.Parent := Self;  // Or, say a TPanel or other container!
      FCurrentFrame.Align := alClient;
    end;
  end;
end;

Quindi, per utilizzarlo, è possibile impostare semplicemente la proprietà ad un'istanza creata del telaio, ad esempio nel caso in OnCreate:

MyFrame1.CurrentFrame := TSomeFrame.Create(nil);

Se si vuole sbarazzarsi del telaio, è sufficiente assegnare nil alla proprietà currentFrame:

MYFrame1.CurrentFrame := nil;

Funziona molto bene.

ho una parola per voi: TFrameStack. Semplicemente ciò che suggerisce il nome.

Ha alcuni metodi: PushFrame (Aframe), PopFrame, PopToTop (Aframe), PopToTop (Indice), e alcune proprietà: StackTop; Frames [Index: Integer]; Conte;

  • Dovrebbe essere evidente.

La cornice a StackTop è quello visibile. Quando si fa ops come Indietro / Precedente non avete bisogno di sapere che cosa telaio era prima quello attuale :) Durante la creazione del telaio è possibile creare e spingerlo in una FrameStack.Push go (TAFrame.Create) ecc, che crea chiama il proc BeforeShow e la rende visibile, tornando suo indice nella pila:)

Ma non fanno molto affidamento sui Ereditando i fotogrammi da un antenato comune. Questi telai tutti (nel mio caso) hanno procedure: BeforeShow; BeforeFree; BeforeHide; BeforeVisible. Questi sono chiamati dal Object FrameStack durante la spinta, pop e superiore;

Da modulo principale è sufficiente per accedere FrameStack.Stacktop.whatever. Ho fatto la mia Stack un :) globale quindi è davvero facile accesso da finestre di dialogo aggiuntive / finestre ecc.

Inoltre, non dimenticare di creare un metodo di sostituzione gratuita per liberare tutti i fotogrammi (se il proprietario è pari a zero) nella pila quando l'applicazione è chiusa - un altro vantaggio che non è necessario per tenere traccia di loro in modo esplicito:)

Ci sono voluti solo una piccola quantità di lavoro per creare l'oggetto TFrameStack List. E nella mia app funzionerà come un sogno.

Timbo

Io uso anche l'approccio descritto da @ Tim Sullivan con qualche aggiunta. In ogni fotogramma definisco la procedura di inizializzazione frame - impostazione delle proprietà predefinite dei suoi componenti.

TAnyFrame = class(TFrame)
  public
    function initFrame() : boolean; // returns FALSE if somesthing goes wrong
    ...
end;

E dopo che il telaio è stato creato io chiamo questa procedura.

aFrame := TAnyFrame.Create(nil);
if not aFrame.initFrame() then
  FreeAndNil(aFrame)
else
  ... // Associate frame with form and do somthing usefull

Anche quando si cambia cornice a vista non è necessario distruggere quella precedente, perché può contenere i dati utili. Immaginate di ingresso alcuni dati in un primo telaio / pagina, poi vai a quello successivo, e poi decide di cambiare i dati sulla prima pagina di nuovo. Se distruggi fotogramma precedente hai perso i dati in esso contenuti e necessario ripristinarli. La soluzione è quella di mantenere tutti i frame creati e crea nuovo telaio solo quando è necessario.

page_A : TFrameA;
page_B : TFrameB;
page_C : TFrameC;
current_page : TFrame;

// User click button and select a frame/page A
if not assigned(page_A) then begin
  // create and initialize frame
  page_A := TFrameA.Create(nil);
  if not page_A.initFrame() then begin
    FreeAndNil(page_A);
    // show error message
    ...
    exit;
  end;
  // associate frame with form
  ...
end;
// hide previous frame
if assigned(current_page) then
  current_page.hide();
// show new page on the form
current_page := page_A;
current_page.Show();
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top