2009-11-25 4 views
0

Je suis actuellement en train de développer une application Delphi qui aura besoin d'un historique de navigation et j'essaie de comprendre comment mettre en œuvre exactement cela.Cadres et historique de navigation en Delphi

L'application a 2 modes. Parcourir et Détails. Les deux conçus comme des cadres.

Après une recherche, un nombre approprié de cadres de recherche sont créés dans le panneau 1 et remplis. A partir d'un cadre de navigation, nous pouvons soit ouvrir le cadre de détail, en remplaçant le contenu du panneau 1 par le contenu du cadre de détail. Une nouvelle recherche peut également être lancée, en remplaçant l'ensemble de résultats actuel par un nouvel ensemble. À partir du cadre de détail, nous pouvons modifier les détails ou générer de nouvelles recherches. Certaines recherches sont uniquement disponibles dans le cadre de détail. D'autres à partir des cadres de recherche ou du cadre de détail.

Chaque fois qu'un utilisateur affiche le cadre de détail, ou génère une nouvelle recherche, je veux enregistrer cette action et être capable de le répéter. D'autres actions comme des modifications ou "plus de détails" ne seront pas enregistrées. (De toute évidence, si un utilisateur recule de quelques pas, il se dirige vers un chemin de recherche différent.)

Dans mon esprit, je veux enregistrer les appels de procédure qui ont été faits dans une liste, par ex.

SearchByName(Search.Text); 
SearchByName(ArchName.Text); 
DisplayDetails(JobID); 
SearchByName(EngineerName.Text); 
DisplayDetails(JobID); 

Je peux juste (en quelque sorte) appeler chaque élément afin que je vais bak et en avant ...

+0

Veuillez préciser si l'historique de navigation doit être conservé ou s'il est OK lorsqu'il est perdu lorsque le programme est arrêté. Les options de mise en œuvre varieront grandement en fonction de cela. – mghie

+0

Il n'est pas nécessaire d'être persistant une fois l'application fermée. Le but de ce que j'essayais de demander était de savoir comment stocker et appeler les gestionnaires de méthodes. –

Répondre

1

En réponse à la demande de Dan Kelly pour stocker la fonction: Cependant ce que je vois ne peux toujours pas comment j'appelle la fonction stockée -

Ce que vous faites référence est le stockage d'une méthode gestionnaire. Le code ci-dessous le démontre.Mais, comme vous l'avez indiqué vous-même, vous pourriez faire une grande déclaration de cas.

Tout cela fonctionnera. Mais une façon encore plus «éloquente» de tout faire est de stocker des pointeurs d'objets. Par exemple, si une recherche ouvre une autre recherche, vous passez un pointeur du premier au second. Puis, dans la seconde, si vous voulez vous y référer, vous avez un pointeur (vérifiez d'abord qu'il n'est pas nul/gratuit). Cette approche est beaucoup plus orientée objet et se prêterait mieux à des situations où quelqu'un pourrait fermer l'un des cadres hors séquence.

unit searchit; 

interface 

uses 
    Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, 
    Dialogs, StdCtrls; 

type 
    TSearchObject = class 
    FSearchValue: String; 
    FOnEventClick: TNotifyEvent; 
    constructor Create(mSearchValue: string; mOnEventClick: TNotifyEvent); 
    procedure FireItsEvent; 
end; 

type 
    TForm1 = class(TForm) 
    SearchByName: TButton; 
    GoBack: TButton; 
    DisplayDetails: TButton; 
    searchfield: TEdit; 
    jobid: TEdit; 
    procedure FormCreate(Sender: TObject); 
    procedure SearchByNameClick(Sender: TObject); 
    procedure GoBackClick(Sender: TObject); 
    procedure DisplayDetailsClick(Sender: TObject); 
    private 
    { Private declarations } 
    SearchObjectsList: TStringList; 
    procedure DisplayDetailFunction(Sender: TObject); 
    procedure SearchByNameFunction(Sender: TObject);   
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

constructor TSearchObject.Create(mSearchValue: string;mOnEventClick: TNotifyEvent); 
begin 
    FOnEventClick := mOnEventClick; 
    FSearchValue := mSearchValue; 
end; 

{$R *.dfm} 

procedure TSearchObject.FireItsEvent; 
begin 
    if Assigned(FOnEventClick) then 
    FOnEventClick(self); 
end; 

procedure TForm1.SearchByNameClick(Sender: TObject); 
var 
    mSearchObject: TSearchObject; 
begin 
    mSearchObject := TSearchObject.Create(SearchField.Text,SearchByNameFunction); 
    SearchObjectsList.AddObject(SearchField.Text,mSearchObject); 
end; 

procedure TForm1.DisplayDetailFunction(Sender: TObject); 
var 
    mSearchObject: TSearchObject; 
begin 
    mSearchObject := TSearchObject(Sender); 
    ShowMessage('This is the Display Detail Event. The value of the JobID is '+mSearchObject.FSearchValue); 
end; 

procedure TForm1.SearchByNameFunction(Sender: TObject); 
var 
    mSearchObject: TSearchObject; 
begin 
    mSearchObject := TSearchObject(Sender); 
    ShowMessage('This is the SearchByName Event. The value of the Search Field is '+mSearchObject.FSearchValue); 
end; 


procedure TForm1.DisplayDetailsClick(Sender: TObject); 
var 
    mSearchObject: TSearchObject; 
begin 
    mSearchObject := TSearchObject.Create(jobid.text,DisplayDetailFunction); 
    SearchObjectsList.AddObject(jobid.text,mSearchObject); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    SearchObjectsList := TStringList.Create; 
end; 

procedure TForm1.GoBackClick(Sender: TObject); 
var 
    mSearchObject: TSearchObject; 
begin 
    if SearchObjectsList.count=0 then 
    showmessage('Cannot go Back!') 
    else begin 
    mSearchObject := TSearchObject(SearchObjectsList.Objects[SearchObjectsList.count-1]); 
    mSearchObject.FireItsEvent; 

    SearchObjectsList.Delete(SearchObjectsList.count-1); 

    end; 
end; 

end. 
+0

C'est exactement ce que je pensais. J'avais aussi considéré la route du pointeur, mais j'avais encore moins idée de l'endroit où commencer cette route (les pointeurs, malheureusement, restent un de mes spots aveugles de programmation) –

1

piste de tout Garder un TStringList; quand ils vont "Retour" vous supprimez de la liste de chaînes. C'est une sorte de prototype:

type 
    TSearchObject = class 
    FSearchFunction,FSearchValue: String; 
    constructor Create(mSearchFunction,mSearchValue: string); 
end; 

type 
    TForm1 = class(TForm) 
    SearchByName: TButton; 
    GoBack: TButton; 
    DisplayDetails: TButton; 
    searchfield: TEdit; 
    procedure FormCreate(Sender: TObject); 
    procedure SearchByNameClick(Sender: TObject); 
    procedure GoBackClick(Sender: TObject); 
    procedure DisplayDetailsClick(Sender: TObject); 
    private 
    { Private declarations } 
    SearchObjectsList: TStringList; 
    jobid: String; //not sure how you get this 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

constructor TSearchObject.Create(mSearchFunction,mSearchValue: string); 
begin 
    FSearchFunction := mSearchFunction; 
    FSearchValue := mSearchValue; 
end; 

{$R *.dfm} 

procedure TForm1.SearchByNameClick(Sender: TObject); 
var 
    mSearchObject: TSearchObject; 
begin 
    mSearchObject := TSearchObject.Create('SearchByName',SearchField.Text); 
    SearchObjectsList.AddObject(SearchField.Text,mSearchObject); 
end; 

procedure TForm1.DisplayDetailsClick(Sender: TObject); 
var 
    mSearchObject: TSearchObject; 
begin 
    mSearchObject := TSearchObject.Create('DisplayDetails',JobID); 
    SearchObjectsList.AddObject(JobId,mSearchObject); 
end; 

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    SearchObjectsList := TStringList.Create; 

end; 

procedure TForm1.GoBackClick(Sender: TObject); 
var 
    mSearchObject: TSearchObject; 
begin 
    if SearchObjectsList.count=0 then 
    showmessage('Cannot go Back!') 
    else begin 
    mSearchObject := TSearchObject(SearchObjectsList.Objects[SearchObjectsList.count-1]); 
    if mSearchObject.FSearchFunction ='SearchByName' then 
     ShowMessage('Value of Search Field:'+mSearchObject.FSearchValue) 
    else 
     ShowMessage('Value of JobID:'+mSearchObject.FSearchValue); 
    SearchObjectsList.Delete(SearchObjectsList.count-1); 

    end; 
end; 
+0

Merci C'est bon, et résout une de mes questions (non déclarée) quant à la façon dont je stocke les valeurs ainsi que la commande. Cependant ce que je ne vois toujours pas, c'est comment j'appelle la fonction stockée - dans votre exemple vous l'utilisez pour décider quel ShowMessage utiliser ... Je devrais appeler la procédure et passer le paramètre stocké ... –

+0

En fait, je suis dense - une réponse est utilisée si/instructions de cas pour prendre la décision dans la routine GoBackClick ... (Pouvez-vous faire l'autre option si?) –

0

Une autre option serait d'utiliser mon wizard framework, qui fait avec TForms mais peut facilement être ajustée aussi utiliser des cadres. Le concept est que chaque forme de résumé sait comment créer ses détails appropriés. Dans votre cas, le framework est plus un exemple de la façon de le faire, plutôt qu'une solution prête à l'emploi.

0

En complément de MSchenkel réponse.

Pour persister la liste entre les exécutions de programme, utilisez un fichier ini.

Voici l'idée. Vous devez l'adapter. Spécialement, vous devez trouver le moyen de convertir l'objet en chaîne et la chaîne en objet, esquissé ici comme ObjectToString(), StringToStringID et StringToObject().

A l'événement OnClose, écrivez la liste dans le fichier ini.

const 
    IniFileName = 'MYPROG.INI'; 
    MaxPersistedObjects = 10; 

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); 
var 
    ini: TIniFile; 
    i: integer; 
    cnt: integer; 
begin 
    ini:=TIniFile.Create(iniFileName); 
    cnt:=SearchObjectsList.Count; 
    if cnt>MaxPersistedObjects then 
    cnt:=MaxPersistedObjects; 
    for i:=1 to MaxPersistedObjects do 
    if i>cnt then 
     ini.WriteString('SearchObjects','SearchObject'+intToStr(i),''); 
    else 
     ini.WriteString('SearchObjects','SearchObject'+intToStr(i), 
     ObjectToString(SearchObjectsList[i-1],SearchObjectsList.Objects[i-1])); 
    ini.Free; 
end; 

et lire de retour à l'événement OnCreate.

procedure TForm1.FormCreate(Sender: TObject); 
var 
    ini: TIniFile; 
    i: integer; 
begin 
    SearchObjectsList := TStringList.Create; 
    ini:=TIniFile.Create(IniFileName); 
    for i:=1 to MaxPersistedObjects do 
    begin 
     s:=ini.ReadString('SearchObjects','SearchObject'+intToStr(i),''); 
     if s<>'' then 
     SearchObjectsList.AddObject(StringToID(s),StringToObject(s)); 
    end; 
    ini.Free; 
end;